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

The script I have creates the 2nd. script just fine. Here is the code:
#!/usr/local/bin/perl -w use strict; my $config = $ARGV[0]; my $date = $ARGV[1]; my $who = $ARGV[2]; my $program = "/nfs/elmo/users/dd/bin/gen-cflowd-config"; my $matrix = "netmatrix"; my $path = "/nfs/elmo/users/dd/config/$date"; my %hash; my $host; my $key; my $script = "script-$date"; die "Usage: $0 <file> <yyyymmdd> <user-name>\n" unless @ARGV == 3; open (CONFIG_FILE, $config) || die "Cannot open $config:$!\n"; while (my $line = <CONFIG_FILE>) { chomp $line; next if ($line =~ /^\#/); my ($router, $cache, $nta, $as, $Sample) = split (' ', $line); $host = (split "-", $nta)[0]; $host =~ tr/0-9//d; push @{$hash{$host}}, $router; } open (STDOUT, ">$script"); print <<END; #! /bin/sh if test ! -d /export/home/ss/flowstats/config/$date then mkdir /export/home/ss/flowstats/config/$date fi END print "\n\n"; foreach $key ( keys %hash) { print "$program $key $matrix "; print "$path/CISCO_$_.clean " for @{$hash{$key}}; print "\n\n"; } system "chmod 755 /export/home/ss/flowstats/config/$date/$script"; system "./export/home/ss/flowstats/config/$date/$script";
What happens is that the script will not create the directory, change the permissions of the newly created script, nor try to even run it.
My UNIX environmental permissions allow for what I'm tring to do. As a matter of fact, when I simply write
#! /bin/sh if test ! -d /export/home/ssesar/flowstats/config/$date then mkdir /export/home/ssesar/flowstats/config/$date fi
it creates the directory. What am I missing here?

BTW, thanks to those who helped my out with this program yesterday.

Replies are listed 'Best First'.
Re: Script which creates 2nd script and runs it
by chipmunk (Parson) on Feb 01, 2001 at 01:36 UTC
    You need to take a close look at your paths, figure out which of the many paths you refer to is the right one, and then make sure you use that one path everywhere.

    open (STDOUT, ">$script"); creates the script in the current directory.

    system "chmod 755 /export/home/ss/flowstats/config/$date/$script"; chmod's the script in a directory with an absolute path.

    system "./export/home/ss/flowstats/config/$date/$script"; runs the script in a directory relative to the current directory.

    I'm not sure why you want to create this shell script, however, instead of just using Perl's builtin filetest operators and mkdir. (There's also a chmod.)

    Update: For the commands that need to be run externally, you should use system or qx//, as suggested in reponse to your node from yesterday.

      This shell script includes the output of other parts of the code, not just what is between END and END. The resultant shell script will run another program several times, each time with different arguments passed to it.
      Look at the bottom of the script. I AM using  system. What I'm saying, is as written, it doesn't work. The file script-$date is written, but that's it!
        You're using system to execute a shell script which then executes other commands. My suggestion is skipping the shell script altogether, and using system to execute those commands directly from Perl.

        For example:

        foreach $key (keys %hash) { my $cmd = "$program $key $matrix "; $cmd .= "$path/CISCO_$_.clean " for @{$hash{$key}}; system($cmd) == 0 # system returns 0 on success or die "system '$cmd' failed: $?"; }
Re: Script which creates 2nd script and runs it
by arturo (Vicar) on Feb 01, 2001 at 03:19 UTC

    It's SOP at this point to remind you that you need to check the return values of system calls (which is more than just calls to system, but here they turn out to be the same thing =).

    You don't want your program to fail silently, you want it to die an agonizing death with something pithy to say about why.

    Unfortunately, system doesn't return its error code in $!, so you'll have to read the documentation on system on your system with perldoc -f system for more info on what to do with the return value. Moreover, system usually returns 0 on success, so yer standard system("foo") or die "$!\n"; is doubly whammied. You can replace the or with and to get around the second whammy, however.

    HTH

    Philosophy can be made out of anything. Or less -- Jerry A. Fodor

Re: Script which creates 2nd script and runs it
by isotope (Curate) on Feb 01, 2001 at 01:26 UTC
    Well, I think your problem is here:
    print <<END; #! /bin/sh if test ! -d /export/home/ss/flowstats/config/$date then mkdir /export/home/ss/flowstats/config/$date fi END
    Your shebang (#!) is going to be printed indented... it must be at the very beginning of the line, no whitespace. The heredoc prints literally what follows, including leading whitespace.

    --isotope
    http://www.skylab.org/~isotope/
      Nope. That's not it.