#! /usr/bin/perl -wl ################################################################# # listfiles # Enhanced version of "listfile" script featured on pp. 217-218 # of "Minimal Perl for UNIX and Linux People", by Tim Maher. # Adds error-checking, symbolic-link handling, and listing of # (non-hidden) files of current directory by default. # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Author: Tim Maher, tim@TeachMePerl.com # Version: Wed Nov 15 10:11:38 PST 2006 ################################################################# # NOTE: Listings are printed in ARGV order (if supplied), or else in # globbing's ASCII-betical order. use strict; { # Scope for MAIN my @listings; # Doesn't handle ls's -a, etc., so discard hyphen-prefixed # options, if any. NOTE: This means filenames can't start with # a hyphen (which would be unconventional anyway). # strip leading -whatever arguments while ( defined $ARGV[0] and $ARGV[0] =~ /^-/ ) { warn "$0: Ignoring option: '$ARGV[0]'\n"; shift; } if (@ARGV) { @listings=list_files ( @ARGV ); } else { @listings=list_files ( <*> ); } { local $,="\n"; print @listings; # print each listing on separate line } } # End of scope for MAIN sub list_files { # load CPAN module whose format_mode() function # converts 0644 --> "-rw-r--r--" use Stat::lsMode; my @lines; # each element will be a listing of one file foreach my $filename ( @_ ) { my ($mode, $nlink, $uid, $gid, $size, $mtime, $rwx_mode, $uid_name, $gid_name, $time, $target ); if (! -l $filename) { # not a symlink # test for existence; "_" is shortcut for $filename -e _ or warn "$0: '$filename'; $!\n" and next; (undef, undef, $mode, $nlink, $uid, $gid, undef, $size, undef, $mtime)=stat _; } else { # for symlinks use "lstat" (undef, undef, $mode, $nlink, $uid, $gid, undef, $size, undef, $mtime)=lstat $filename; $target=readlink $filename; # see what it points to if (! defined $target) { $target='[No Target!]'; warn "$0: Can't read target for '$filename'; $!\n"; } } # convert seconds to time string $time=localtime $mtime; # convert UID-number to string $uid_name=$uid; # keep numeric ID if can't convert to user-name my $x=getpwuid $uid; defined $x and $x =~ /\D/ and $uid_name=$x; # convert GID-number to string $gid_name=$gid; # keep numeric ID if can't convert to user-name $x=getgrgid $gid; defined $x and $x =~ /\D/ and $gid_name=$x; $rwx_mode=format_mode $mode; # octal mode --> rwx format my $listing=sprintf "%s %2d %-6s %-6s %6d %s %s", $rwx_mode, $nlink, $uid_name, $gid_name, $size, $time, $filename; $target and $listing.=" -> $target"; push @lines, $listing; } return @lines; }