Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Using Permissions as a Parameter

by Dr.Avocado (Novice)
on Aug 15, 2007 at 14:54 UTC ( [id://632756]=perlquestion: print w/replies, xml ) Need Help??

Dr.Avocado has asked for the wisdom of the Perl Monks concerning the following question:

Dear Perl masters,
I have a simple piece of code that prints the name of each file in a directory in Unix.
opendir(DIR, "$directoryName"); @files = readdir(DIR); closedir(DIR); foreach $file (@files) { print "$file\n\n"; }
Is there a way I can refrain from printing the file name for files with the l permission activated? Most of the files in the directory have -rwxrwxrwx permissions, but a few have lrwxrwxrwx, and I wish to exclude those. How do I do this?
Thanks for any help.

Replies are listed 'Best First'.
Re: Using Permissions as a Parameter
by clinton (Priest) on Aug 15, 2007 at 14:57 UTC
    You're looking for the -l $file test, which tests for a symbolic link. See -X, as in:

    foreach $file (@files) { next if -l "$directoryName/$file"; print "$file\n\n"; }
    Clint

    Update: Added the directory name as per jwkhran's post below

Re: Using Permissions as a Parameter
by jwkrahn (Abbot) on Aug 15, 2007 at 15:03 UTC
    To correct the two previous posts, you have to include the directory name in the test:
    next if -l "$directoryName/$file";
      Heh... I'm used to using glob() myself. But the -l $file should work either way, once the directory is tacked on. :)
Re: Using Permissions as a Parameter
by jbert (Priest) on Aug 15, 2007 at 16:42 UTC
    Although the answer to your question is "use -l", I wonder if instead of just filtering out the symbolic links, you actually want to filter out everything which is not a plain file (e.g. directories, device nodes, named pipes, sockets, etc).

    In that case, the test you want is '-f'. See "perldoc -f -f" for more details.

    Also, I like to think that the list-processing commands of perl (map, grep) make for very readable (and shorter) code in this sort of situation.

    Some other notes:

    • You don't need to put the scalar $directoryName in quotes. All that does is expand to a string containing $directoryName, you can just pass it in directly.
    • Using file and directory handles like DIR is slightly poor style. The problem is that these are global names shared with the rest of your code. If you had one dir open with DIR and you called another function which opened another dir in the same way, the two handles would conflict. The better way (as with files and 'open') is to use a lexical scalar variable, as below, for the dirhandle.
    • Whenever you do something like opening a dir, it's good to test for failure (a false return from opendir) and if so, to give an error containing the system error code, $!
    my $directoryName = '/tmp'; opendir(my $dh, $directoryName) or die "Can't open dir $directoryName : $!"; my @files = grep { -f "$directoryName/$_" } readdir($dh); closedir($dh); print "$_\n" for @files;
    The last line (using a one-line for-loop with $_) is a little terse, and I don't often write it that way, but it's a useful trick to know.

    Hope you don't mind the extended comment on your post, I thought I'd take the chance to get a few things off my chest :-)

Re: Using Permissions as a Parameter
by archfool (Monk) on Aug 15, 2007 at 14:58 UTC
    print "$file\n\n"  if (not -l $file);

    Use the symbolic link test in this case.

    UPDATE: Darn! Too slow on the draw! ;)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://632756]
Approved by clinton
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (4)
As of 2024-04-23 16:12 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found