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

Can anybody point me in the right direction here. I can execute the following commands just fine from the C shell but cannot run them from a perl script. I get the following error message:

perl export.pl
echo: No such file or directory.
status3 went wrong:256 at export.pl line 24.

The third command relies on the first two commands to set $data_root. When I run echo $data_root from the shell after running the script I get:

data_root: Undefined variable.

Thank you so much for your help.
#! /usr/bin/perl $program = "/bin/csh "; $status1 = system("$program source /exlibris/aleph/a16_1/aleph/proc/un +set_lib_env"); die "status1 went wrong:$?" unless $status1 ==0; $status2 = system("$program source `/exlibris/aleph/a16_1/aleph/exe/de +v_aleph gpo01`/gpo01/prof_library"); die "status2 went wrong:$?" unless $status2 ==0; $status3 = system("$program echo $data_root"); die "status3 went wrong:$?" unless $status3 ==0;

Replies are listed 'Best First'.
Re: Perl system calls in csh Not executing!
by merlyn (Sage) on Aug 18, 2005 at 03:33 UTC
    Every invocation of system is a separate shell. If you want the effects of the "source" command to affect the later steps, you have to do them all in one system invocation.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

Re: Perl system calls in csh Not executing!
by graff (Chancellor) on Aug 18, 2005 at 03:57 UTC
    If you mean that you want a csh environment variable called "data_root" to be set to some value, and you want your third system call to cause that value to be echoed to stdout, then...

    Well, first, merlyn is right, of course, that's a separate shell process from the first two, and so it doesn't know anything about what happened in the previous system calls. On top of that, when you write a system call like this:

    $status = system( "$program arg1 $arg2" );
    perl interprets this to mean that there should be a perl scalar variable called "$arg2", and the value of this variable should be included as the third token in the command line being passed to system().

    Just what are you really trying to accomplish, anyway? Why do you have backticks in the second system call? Why are you using csh at all??

    Apropos of merlyn's comment about how you would need to have these three command lines run in the same shell invocation, here's a little trick you might keep in mind:

    open( SH, "| /bin/csh" ) or die "Can't start subshell: $!"; print SH "echo this is foo bar\n"; print SH "source some_script\n"; print SH "echo \$some_obscure_shell_variable_set_by_some_script\n"; #...

    (Note the backslash in front of the "$", so perl knows that it isn't being used as part of a perl variable name.)

    But really, whatever it is you're trying to do, there probably is a better way.

Re: Perl system calls in csh Not executing!
by davidrw (Prior) on Aug 18, 2005 at 11:43 UTC
    An alternative to opening a pipe as graff suggests (which is a perfectly find solution) is to make an executable shell script that does everything you want and then invoke it with a single system call. This has the advantage that it will probably be useful to you on the commandline as well. For example, make a file called ~/bin/foo and make it executable and contain the source:
    #!/bin/csh source /exlibris/aleph/a16_1/aleph/proc/unset_lib_env if( $? != 0 ){ exit 1 } # i guessed at the whole syntax here source `/exlibris/aleph/a16_1/aleph/exe/dev_aleph gpo01`/gpo01/prof_li +brary if( $? != 0 ){ exit 2 } # i guessed at the whole syntax here echo $data_root if( $? != 0 ){ exit 3 } # i guessed at the whole syntax here
    Note invoke it like $rc = system('/home/yourname/bin/foo'); And then you can inspect $rc >> 8 for the actual exit code to see if it error'd or not. (see perldoc -f system for more details)

    Side note: Csh Programming Considered Harmful

    re: your original code -- note that the $data_root will be interoplated by perl .. to avoid that and pass the literal $data_root to echo you have to escape it like "$program echo \$data_root" or better yet use the multi-parameter syntax of system (perldoc -f system) and do system($program, 'echo $data_root');
Re: Perl system calls in csh Not executing!
by Anonymous Monk on Aug 18, 2005 at 14:20 UTC
    Bless you all! Randal, Graff and Davidrw, your comments were very helpful and certainly set me in the right direction. Just for explanation purposes, I needed to use csh because it's the default shell for the application user and the shell sscripts that I need to interact with from Perl are all in csh. The objective is to automate exporting Oracle tables. The vendor supplies a procedure which uses aliases, which in turn calls a number of csh scripts. This is done manually of course! I could not implement this from Perl because the aliases were not expanding properly. So that's why I decided to automate this using the default shell. The prototype script you provided Graff worked like a charm! I can't thank you guys enough!