Karyn Williams wrote: > I have this script I have been working on where I need to redirect STDOUT > and STDERR to files at the beginning of the script and then back to default > (terminal) at the end of the script. I found an example on-line and used it > and it works, however it generates a warning when running my script.
Try using the example that comes with Perl: perldoc -f open > I would prefer to make that warning go away. This is the output of the script: > > alum# ./match.pl > Name "main::OLDERR" used only once: possible typo at ./match.pl line 38. > Name "main::OLDOUT" used only once: possible typo at ./match.pl line 37. > Records processed: 2 > Kicked as dups: 1 > Kicked as exceptions: 0 > Accounts created: 1 > > This is the script: > > #!/usr/bin/perl > > # match.pl expanded > # Checks the current csv against the passwd file to detect and prevent > creating duplicate accounts > > use strict; > use warnings; > > my $dir = "/usr/local/accounts"; > > my $csv = "isirin.csv"; > my $expin = "exceptions.csv"; > my $pwfile = "/etc/passwd"; > my $expout = "exceptions.log"; > my $clog = "account_change.log"; > my $as400 = "as400.txt"; > my $admiss = "admissions.txt"; > my $err = "error.log"; > > my $description = "SIR Fall 2007"; > > my $date = localtime(); > my ($sec,$min,$hour,$mday,$mon,$year) = (localtime)[0,1,2,3,4,5]; > $mday++; You are incrementing the day of the month so if today is 31 May your string will display the 32nd day of May! > $mon++; > $year += 1900; > my $today = sprintf("%04d%02d%02d-%02d%02d%02d", $year, $mon, $mday, $hour, > $min, $sec); > > # Read in csv file from Accounting and check for existing accounts. > > open (IN, "$dir/$csv") or die "$dir/$csv does not exist. This file must be > available to run this script: $!"; > open (EX, "$dir/$expin") or die "Can't open EX $expin : $!"; > open (PW, "$pwfile") or die "Can't open PW $pwfile : $!"; > open (EXCEP, ">>$dir/$expout") or die "Can't open EXCEP: $!"; > open (OUT, ">>$dir/$clog") or die "Can't open OUT: $!"; > open (AOUT, ">$dir/$as400") or die "Can't open AOUT: $!"; > open (OLDOUT, ">&STDOUT"); > open (OLDERR, ">&STDERR"); > open (STDOUT, ">$dir/$admiss") or die "Can't open STDOUT: $!"; > open (STDERR, ">>$dir/$err") or die "Can't open STDERR: $!"; You should use the three argument form of open and you should *ALWAYS* verify that open succeeded: open IN, '<', "$dir/$csv" or die "$dir/$csv does not exist. This file must be available to run this script: $!"; open EX, '<', "$dir/$expin" or die "Can't open EX $expin : $!"; open PW, '<', $pwfile or die "Can't open PW $pwfile : $!"; open EXCEP, '>>', "$dir/$expout" or die "Can't open EXCEP: $!"; open OUT, '>>', "$dir/$clog" or die "Can't open OUT: $!"; open AOUT, '>', "$dir/$as400" or die "Can't open AOUT: $!"; open OLDOUT, '>&', \*STDOUT or die "Can't dup STDOUT: $!"; open OLDERR, '>&', \*STDERR or die "Can't dup STDERR: $!"; open STDOUT, '>', "$dir/$admiss" or die "Can't open STDOUT: $!"; open STDERR, '>>', "$dir/$err" or die "Can't open STDERR: $!"; > my $pwf; > my $exp; > my $gecos; > my $login; > my $rcount = 0; > my $acount = 0; > my $ecount = 0; > my $lcount = 0 ; > > my @line = <IN>; Why are you reading the entire file into memory if you don't really have to? > printf STDOUT ("$date\n"); That should be print instead of printf: print STDOUT "$date\n"; printf() requires that the first string is a format string and will interpolate certain characters. > # Slurp the /etc/passwd file into one string and then search for matching > Student IDs in that > # string. Use this later for checking unused loginnames also. > > while (<PW>) { > $pwf .= $_; > } my $pwf = do { local $/; <PW> }; > while (<EX>) { > $exp .= $_; > } my $exp = do { local $/; <EX> }; > # Create GECOS and login info and then create account using pw > > foreach my $line (@line) { You probably should use a while loop instead of a foreach loop. > next if $line =~ /^nameid/; > next if $line =~ /^$/; > next if $line =~ /^\s+$/; > # file format is nameid,first,init,last > #print $line; > chomp $line; > $rcount++; > my ($sid,$name) = split(/,/, $line,2); > if ($pwf =~ /\b$sid\b/) { You should probably store the $sid values in a hash. > printf EXCEP ("$date, $name, $sid, possible dup You should use print instead of printf. > account\n"); $acount++; > } elsif ($exp =~ /\b$sid\b/) { You should probably store the $sid values in a hash. > printf EXCEP ("$date, $name, $sid, listed in You should use print instead of printf. > exceptions.csv\n"); $ecount++; > } else { > > my ($first, $initial, $last) = split(/,/, $name, 3); > # Create gecos info > $last =~ s/[",]//g; > $first =~ s/[",]//g; > $initial =~ s/[",]//g; tr/",//d for $first, $initial, $last; > if ($initial) { > $gecos = "\"$first $initial $last, $sid, $description\""; > } else { > $gecos = "\"$first $last, $sid, $description\""; } > #print "GECOS IS $gecos\n"; > # Now guess at a login > my $lfirst = $first; > $lfirst =~ s/[^a-zA-Z]//g; > #(my $lfirst = $first) =~ s/[^a-zA-Z]//g); > my @last = split(/\s/, $last, 2); > my $llast = $last[0]; You don't need the array if you are only extracting one value: my $llast = ( split ' ', $last )[ 0 ]; > $llast =~ s/[-\s]//g; > #print "LoginLast is $llast\n"; > if (length($lfirst) + length($llast) <= 16) { > $login = $lfirst . $llast; > } else { > my $f = substr(($lfirst),0,1); > $login = $f . $llast; > } > $login = lc($login); > #print "Login is $login\n"; > #printf STDOUT ("$first $initial $last, $sid, $login, passwd\n"); > printf STDOUT ("$first $initial $last, $sid, $login, "); You should use print instead of printf. > #This next line is for testing purposes > system("pw useradd -n $login -c $gecos -m -s /bin/ftpshell -N"); You should verify that 'pw' executed correctly: system( 'pw', 'useradd', '-n', $login, '-c', $gecos, '-m', '-s', '/bin/ftpshell', '-N' ) == 0 or die "Cannot run 'pw' $?"; > #system("pw useradd -n $login -c $gecos -m -s /bin/ftpshell -w > random"); > printf OUT ("$date Account Added, $first $initial $last, $login, You should use print instead of printf. > $sid\n"); > printf AOUT ("$sid, $first $initial $last, $login\n"); You should use print instead of printf. > $lcount++; > } > } > > close IN; > close OUT; > close AOUT; > close STDOUT; > close STDERR; > close EX; > close PW; > close EXCEP; > > rename ("$dir/$csv", "$dir/$csv.$today") or die "Can't rename $dir/$csv : $!"; > > open(STDOUT, ">&OLDOUT"); > open(STDERR, ">&OLDERR"); You should use the three argument form of open and you should *ALWAYS* verify that open succeeded: open STDOUT, '>&', \*OLDOUT or die "Cannot dup OLDOUT: $!"; open STDERR, '>&', \*OLDERR or die "Cannot dup OLDERR: $!"; > print "Records processed: $rcount\n"; > print "Kicked as dups: $acount\n"; > print "Kicked as exceptions: $ecount\n"; > print "Accounts created: $lcount\n"; > > # send via e-mail output of this script. > > my $to = "To: [EMAIL PROTECTED]"; > my $from = "From: [EMAIL PROTECTED]"; > my $subject = "Subject: Test Output for SIRs"; > my $sendmail = "/usr/sbin/sendmail -t"; > > my @files = ("$dir/$as400", "$dir/$admiss"); > my @mail = (); > > foreach my $file (@files) { > > open (MAIL, "|$sendmail") or die "Can't open $sendmail: $!"; > open (AOUT, "<$file") or die "Can't open AOUT for read: $!"; > > print MAIL "$to\n"; > print MAIL "$from\n"; > print MAIL "$subject\n"; > > @mail = <AOUT>; > foreach my $line (@mail) { > print MAIL $line; > } You don't need the array or loop there: print MAIL "$to\n", "$from\n", "$subject\n", <AOUT>; > close (MAIL); When you close a piped open you should verify that it closed correctly: perldoc -f close > close AOUT; > > } > > # end of script John -- Perl isn't a toolbox, but a small machine shop where you can special-order certain sorts of tools at low cost and in short order. -- Larry Wall -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/