the file is there.. I know it is.
Hello everyone, I am starting to work on a script that is going to process a few files in some users directories. I thought I would do some checking on the file to make sure they are there and to make sure they are really files. I thought it was going to be pretty straight forward, until I ran it for the first time. Sometimes the script sees the file for one user but not the next ( that I know is there)? I must be misunderstanding something small, but I can't figure it out. Can anyone offer any suggestions? Thanks, Chad __ #!/usr/local/bin/perl eval 'exec /usr/local/bin/perl -S $0 ${1+$@}' if 0; #$running_under_some_shell use strict; use warnings; use Sys::Hostname; $|++; use vars qw( $server $pwdfile @users ); $server = hostname(); $pwdfile = '/etc/passwd'; # get users open (PASSWD,$pwdfile) or die Cannot open passwd file: $!; while (my $pwdline = PASSWD) { my ($user,$home,$shell) = (split /:/, $pwdline)[0,5,6]; next if ( $home !~ /^\/home/ || $shell !~ /^\/bin/ || $user eq ftp || $user eq www); push @users, $user; } close (PASSWD); foreach my $user(@users) { print Starting $user...\n; #print glob (/home/$user/*-logs/old/200312/access-log.31-*.gz).\n; $user = trim($user); my $decfile = glob (/home/$user/*-logs/old/200312/access-log.31-*.gz); my $janfile = glob (/home/$user/*-logs/old/200401/access-log.01-*.gz); if (!$decfile) { print \t\\Could not find Dec 31,2003 access log.\n; next; } elsif (!-f $decfile) { print \t\\Dec 31,2003 access log is not a file.\n; next; } elsif (!$janfile) { print \t\\Could not find Jan 01,2004 access log.\n; next; } elsif (!-f $janfile) { print \t\\Jan 01,2004 access log is not a file.\n; next; } else { print \t\\$user has both access logs.\n; } } # subs sub trim { my @in = @_; for (@in) { s/^\s+//; s/\s+$//; s/\n//g; } return wantarray ? @in : $in[0]; } -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
Re: the file is there.. I know it is.
chad kellerman said: Hello everyone, I am starting to work on a script that is going to process a few files in some users directories. I thought I would do some checking on the file to make sure they are there and to make sure they are really files. I thought it was going to be pretty straight forward, until I ran it for the first time. Sometimes the script sees the file for one user but not the next ( that I know is there)? I must be misunderstanding something small, but I can't figure it out. Can anyone offer any suggestions? You are using glob in a scalar context. This is not what you want. perldoc -f glob foreach my $user(@users) { print Starting $user...\n; #print glob (/home/$user/*-logs/old/200312/access-log.31-*.gz).\n; $user = trim($user); my $decfile = glob my ($decfile) = glob (/home/$user/*-logs/old/200312/access-log.31-*.gz); Finding a use for the current behaviour is left as an exercise for the reader. -- Paul Johnson - [EMAIL PROTECTED] http://www.pjcj.net -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
Re: the file is there.. I know it is.
Chad Kellerman wrote: Hello everyone, Hello, I am starting to work on a script that is going to process a few files in some users directories. I thought I would do some checking on the file to make sure they are there and to make sure they are really files. I thought it was going to be pretty straight forward, until I ran it for the first time. Sometimes the script sees the file for one user but not the next ( that I know is there)? I must be misunderstanding something small, but I can't figure it out. Can anyone offer any suggestions? Certainly. #!/usr/local/bin/perl eval 'exec /usr/local/bin/perl -S $0 ${1+$@}' if 0; #$running_under_some_shell Do you really need those two lines? use strict; use warnings; use Sys::Hostname; $|++; use vars qw( $server $pwdfile @users ); In most modern Perls you would use our() instead of use vars. our ( $server, $pwdfile, @users ); $server = hostname(); $pwdfile = '/etc/passwd'; Most Perl programmers advocate declaring and defining your variables at the same time. our $server = hostname(); our $pwdfile = '/etc/passwd'; # get users open (PASSWD,$pwdfile) or die Cannot open passwd file: $!; while (my $pwdline = PASSWD) Perl provides a built-in function getpwent() that reads from the password file and also the User::pwent module. { my ($user,$home,$shell) = (split /:/, $pwdline)[0,5,6]; next if ( $home !~ /^\/home/ || $shell !~ /^\/bin/ || $user eq ftp || $user eq www); push @users, $user; } close (PASSWD); foreach my $user(@users) { print Starting $user...\n; #print glob (/home/$user/*-logs/old/200312/access-log.31-*.gz).\n; $user = trim($user); You are modifying the user entry returned from the passwd file. Are you sure you want to do that? (Hint: probably not.) my $decfile = glob (/home/$user/*-logs/old/200312/access-log.31-*.gz); my $janfile = glob (/home/$user/*-logs/old/200401/access-log.01-*.gz); if (!$decfile) { print \t\\Could not find Dec 31,2003 access log.\n; next; } elsif (!-f $decfile) { print \t\\Dec 31,2003 access log is not a file.\n; next; } elsif (!$janfile) { print \t\\Could not find Jan 01,2004 access log.\n; next; } elsif (!-f $janfile) { print \t\\Jan 01,2004 access log is not a file.\n; next; } else { print \t\\$user has both access logs.\n; } You can simplify that a bit: my @files = grep -f, glob /home/$user/*-logs/old/{200312,200401}/access-log.{31,01}-*.gz; print \t\\$user has both access logs.\n if @files == 2; } # subs sub trim { my @in = @_; for (@in) { s/^\s+//; s/\s+$//; s/\n//g; } return wantarray ? @in : $in[0]; } John -- use Perl; program fulfillment -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
Re: the file is there.. I know it is.
Paul Johnson wrote: chad kellerman said: I am starting to work on a script that is going to process a few files in some users directories. I thought I would do some checking on the file to make sure they are there and to make sure they are really files. I thought it was going to be pretty straight forward, until I ran it for the first time. Sometimes the script sees the file for one user but not the next ( that I know is there)? I must be misunderstanding something small, but I can't figure it out. Can anyone offer any suggestions? You are using glob in a scalar context. This is not what you want. perldoc -f glob Interestingly enough it works on my system. Scalar and list context both return the first file name from the glob. John -- use Perl; program fulfillment -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
Re: the file is there.. I know it is.
On Fri, Jan 16, 2004 at 11:47:59AM -0800, John W. Krahn wrote: Paul Johnson wrote: chad kellerman said: I am starting to work on a script that is going to process a few files in some users directories. I thought I would do some checking on the file to make sure they are there and to make sure they are really files. I thought it was going to be pretty straight forward, until I ran it for the first time. Sometimes the script sees the file for one user but not the next ( that I know is there)? I must be misunderstanding something small, but I can't figure it out. Can anyone offer any suggestions? You are using glob in a scalar context. This is not what you want. perldoc -f glob Interestingly enough it works on my system. Scalar and list context both return the first file name from the glob. Right, the first time round the loop. But the behaviour is different the next time, as chad originally reported. $ cat globtest #!/bin/perl -l mkdir tst; chdir tst; open F, tst1; close F; print scalar glob * for 1..4; printglob * for 1..4; $ perl globtest tst1 tst1 tst1 tst1 tst1 tst1 $ -- Paul Johnson - [EMAIL PROTECTED] http://www.pjcj.net -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
Re: the file is there.. I know it is.
Paul Johnson wrote: On Fri, Jan 16, 2004 at 11:47:59AM -0800, John W. Krahn wrote: Paul Johnson wrote: chad kellerman said: I am starting to work on a script that is going to process a few files in some users directories. I thought I would do some checking on the file to make sure they are there and to make sure they are really files. I thought it was going to be pretty straight forward, until I ran it for the first time. Sometimes the script sees the file for one user but not the next ( that I know is there)? I must be misunderstanding something small, but I can't figure it out. Can anyone offer any suggestions? You are using glob in a scalar context. This is not what you want. perldoc -f glob Interestingly enough it works on my system. Scalar and list context both return the first file name from the glob. Right, the first time round the loop. But the behaviour is different the next time, as chad originally reported. Yes. This is documented in perlop.pod. perldoc perlop [snip] A (file)glob evaluates its (embedded) argument only when it is starting a new list. All values must be read before it will start over. In list context, this isn't important because you automatically get them all anyway. However, in scalar context the operator returns the next value each time it's called, or C run out. As with filehandle reads, an automatic `defined' is generated when the glob occurs in the test part of a `while', because legal glob returns (e.g. a file called 0) would otherwise terminate the loop. Again, `undef' is returned only once. So if you're expecting a single value from a glob, it is much better to say ($file) = blurch*; than $file = blurch*; because the latter will alternate between returning a filename and returning false. John -- use Perl; program fulfillment -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response