Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Traversing through a directory structure

by TStanley (Canon)
on Mar 02, 2005 at 20:13 UTC ( [id://435998]=perlquestion: print w/replies, xml ) Need Help??

TStanley has asked for the wisdom of the Perl Monks concerning the following question:

I need to create a listing of file by directory, and the permissions of the files within that directory. Here is my code so far:
#!/opt/perl5/bin/perl -w use strict; use File::Find; ## I'm writing the file listings in this directory my $WriteDirectory="/home/mis/tstanley/Migrate"; ## This is the directory I want to traverse through my $TraverseDirectory="/dsmpayroll"; finddepth(&perms, $TraverseDirectory); sub perms{ my $pwd=`pwd`; # Get the directory I'm in my $file=$pwd; $file=~s/\//\./g; # Change the "/" into "." my $perms=`ls -l`; my $acl=`lsacl *`; open FH, ">$WriteDirectory/$file"||die"Can't open $file: $!\n"; print FH "$pwd"; print FH "$perms"; print FH "$acl"; close FH; }
There are several files and directories under the directory that I'm searching and there has to be an easier way than by going through each directory by hand.

TStanley
--------
The only thing necessary for the triumph of evil is for good men to do nothing -- Edmund Burke

Replies are listed 'Best First'.
Re: Traversing through a directory structure
by kvale (Monsignor) on Mar 02, 2005 at 20:20 UTC
    Try 'ls -lR' on unix systems :)

    More seriously, if you want the permissions for each file in each directory, you must look at each file in each directory,

    -Mark

Re: Traversing through a directory structure
by dmorelli (Scribe) on Mar 02, 2005 at 20:39 UTC
    Couple of things.

    First, I would keep the output file open during the whole find operation, by wrapping it around the finddepth:

    open FH, ">$WriteDirectory/$file" || die "Can't open $file: $!"; finddepth(&perms, $TraverseDirectory); close FH;

    Second, you don't need to backtick-execute pwd. The dir is in $File::Find::dir
    see: perldoc File::Find

    Just curious, are you doing depth-first for a specific reason?

    There are several files and directories under the directory that I'm searching and there has to be an easier way than by going through each directory by hand.

    If you really need to visit all the files like this to gather perms info, I don't think there really is an easier way than File::Find

    Update: Trying this out on my system, I see it gives the "strict refs" complaint. It needs to be:

    finddepth(\&perms, $TraverseDirectory);

      open FH, ">$WriteDirectory/$file" || die "Can't open $file: $!";

      You either mean open( FH, ">..." ) || die "..." or open FH, ">..." or die "...". Your code will never execute the die statement because of the precedence problem.

      freebie:~ 601> perl -MO=Deparse,-p open FH, ">$WriteDirectory/$file" || die "Can't open $file: $!"; open(FH, (">$WriteDirectory/$file" || die("Can't open $file: $!")));
Re: Traversing through a directory structure
by RazorbladeBidet (Friar) on Mar 02, 2005 at 20:30 UTC
    Try here which talks about stat and Fcntl. That might point you in the right direction. In fact, there is a section on viewing permissions with Fcntl
    --------------
    It's sad that a family can be torn apart by such a such a simple thing as a pack of wild dogs
Re: Traversing through a directory structure
by crashtest (Curate) on Mar 02, 2005 at 23:10 UTC
    If you're working on a UNIX system (and I suspect from your task and your code that you are), you might be better off using the find command to list all of your directories, then using a (simpler) Perl script to do your processing.

    For instance, you could try something like this from the shell:
    find /dsmpayroll -type d | perl -n saveinfo.pl

    ... where saveinfo.pl reads:
    #!/usr/bin/perl -w use strict; my $output; $output .= $_ for ($_, qx/ls -l $_/, qx/lsac */); # Get output for fil +e # Print output to file s!/!.!g; # Generate suitable filename open FH, ">/home/mis/tstanley/Migrate/$_" or die $!; print FH $output;
    No need to figure out how to pass a function reference (which dmorelli points out may be the culprit in your original script). More importantly, the find command allows you to specify many search parameters, something which may be harder to do programmatically with Perl.

    Check the manpages for find (and perl, if you're unfamiliar with the -n switch).
Recursive functions
by jhourcle (Prior) on Mar 03, 2005 at 00:24 UTC
    Have you considered using a recursive function?
    #!/usr/bin/perl -- use strict; use warnings; my $LogFile = '/tmp/report.txt'; open ( OUTPUT, '>', $LogFile ) or die "Can't write to $LogFile : $!"; get_permissions ( $_ ) foreach @ARGV; close (OUTPUT) or die "Can't save $LogFile : $!"; sub get_permissions { my $directory = shift; opendir (DIR, $directory) or warn "Can't open directory $directory : $!" and return; my @files = grep { !m/^.{1,2}$/ } readdir DIR; closedir (DIR); foreach my $file (@files) { # do whatever you want for each file # see 'stat' for all but the acls print OUTPUT `ls -ld '$directory/$file'`, `lsac '$directory/$file'`; # and recurse on directories if (-d "$directory/$file") { get_permissions("$directory/$file"); } } }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://435998]
Approved by Limbic~Region
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-24 11:46 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found