Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
So I have been playing around with perl the last week and trying to get a handle on it. Im hardly able to write anything decent without having perlmonks or perldoc open though, but I am learning!

Wanted to know what/how I could improve the following code or in what ways you would have done it differently. I really like seeing more than one approach, and I need help pointing out my pitfalls.

Its very simple code, just traverses a specified directory and changes the permissions for files and/or directories. It is my perl way of doing the following with GNU Find.
find [base directory] -type [f|d] -exec chmod [perm] {} \;

Here it is, input greatly appreciated. Im still a newbie though.
#!/usr/bin/perl -w use strict; use Getopt::Long; use File::Find; my %opts = ( verbose => '', directory => './', filemode => '', dirmode => '' ); if(!GetOptions('verbose' => \$opts{'verbose'}, 'filemode:s' => \$opts{'filemode'}, 'dirmode:s' => \$opts{'dirmode'})) { usagedie(); } #make sure each argument passed is either a file or directory foreach (@ARGV) { usagedie() if (!-f || !-d); } #we need to perform at least one option usagedie() if (!$opts{'filemode'} && !$opts{'dirmode'}); #use default directory if argument not set on command line find(\&fileop, $opts{'directory'}) unless @ARGV; find(\&fileop, @ARGV) if @ARGV; sub fileop { #set the right permissions based on if a file or a directory #only set permissions of the mode is set chmod oct($opts{'filemode'}), $_ if -f && $opts{'filemode'}; chmod oct($opts{'dirmode'}), $_ if -d && $opts{'dirmode'}; print $File::Find::name . "\n" if $opts{'verbose'} && (-f || -d); } sub usagedie { print "Usage: setperm.pl [-v] [-f perm] [-d perm] [Directory]\n"; print "-v, --verbose\t show files changed by script\n"; print "-f, --filemode\t octal mode to change files to\n"; print "-d, --dirmode\t octal mode to change directories to\n"; exit(0); }

Updated Code:
#!/usr/bin/perl -w use strict; use Getopt::Long; use File::Find; my %opts = ( verbose => '', filemode => '', dirmode => '' ); if (!GetOptions(\%opts, 'verbose', 'filemode:s', 'dirmode:s')) { usagedie(); } #make sure each argument passed is either a file or directory foreach (@ARGV) { usagedie() if (!-f && !-d); } #we need to perform at least one option usagedie() if (!$opts{'filemode'} && !$opts{'dirmode'}); #make sure correct octal values were used $opts{'filemode'} = chkperm('File', $opts{'filemode'}); $opts{'dirmode'} = chkperm('Directory', $opts{'dirmode'}); #use default directory if argument not set on command line find(\&fileop, @ARGV ? @ARGV : './'); sub fileop { #set the right permissions based on if a file or a directory #only set permissions if the mode is set if (-f && $opts{'filemode'}) { chmod $opts{'filemode'}, $_; } elsif (-d && $opts{'dirmode'}) { chmod $opts{'dirmode'}, $_; } else { #dont print if we didnt modify file perms return; } print $File::Find::name . "\n" if $opts{'verbose'}; } sub chkperm { my ($type, $perm) = @_; #zero length strings are defined values #our $perm 's by default are set to '' if ($perm) { return ($perm =~ /^[0-7]{4}$/) ? oct($perm) : die "Incorrect $type mode $perm\n"; } return; } sub usagedie { print "Usage: setperm.pl [-v] [-f perm] [-d perm] [Directory]\n"; print "-v, --verbose\t show files changed by script\n"; print "-f, --filemode\t octal mode to change files to\n"; print "-d, --dirmode\t octal mode to change directories to\n"; exit(1); }

Thanks to all of ya'll who helped out. I tested it a few times and it worked perfect, I will test more, but I wanted to show what the combined efforts did to the script before it went off the front page.

I'll be adding an exclude option soon too. This will allow you to exclude directories or files. Thanks!

In reply to How would you go about it? by pcassell

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (3)
As of 2024-04-18 04:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found