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

I have a perl script where i am setting up the C-shell environment variables. example code is as below
sub cimages { system("setenv GENESIS_DIR /genesis/customers/ckt-imgs;setenv GENE +SIS_EDIR /genesis/e90;/genesis/e90/get/get"); }
for some reason, perl script is not setting up this environment variable. If i use all 'setenv' in one line using semicoln as shown above, it prompts the error message "sh setenv command not found", But if i use 'setenv' one per lin then there is no error mesg but ENV variable is not setting. Pls help me how can i setup multiple ENV variables and run the application. FYI : I am using Fedora Linux 4 and Perl V5.8.6

Replies are listed 'Best First'.
Re: Perl & Cshell
by Hue-Bond (Priest) on May 11, 2006 at 13:42 UTC

    system runs your commands using /bin/sh. If /bin/sh is a link to a Bourne shell (it's likely), the error you're seeing will occur. setenv is not a valid Bourne shell command.

    You can alter the environment of your Perl script with the %ENV hash:

    ## untested { local %ENV; $ENV{'GENESIS_DIR'} = '/genesis/customers/ckt-imgs'; $ENV{'GENESIS_EDIR'} = '/genesis/e90'; system '/genesis/e90/get/get'; }

    --
    David Serrano

Re: Perl & Cshell
by liverpole (Monsignor) on May 11, 2006 at 14:06 UTC
    What Hue-Bond said is correct.  Using the %ENV hash is the best and simplest way to set environment variables.

    It's worth pointing out that setting environment variables in a Perl script, however, will not change your shell's environment variables.  That's because you are running Perl in a subprocess, which has its own environment variable list; as soon as the Perl script exits, you're back with the environment variables that the parent had originally.

    To test this is as easy as running the following script:

    #!/usr/bin/perl -w use strict; use warnings; $ENV{'abc'} = 'def'; system('echo $abc');
    When you run this, you should see def printed.  But when you're back to your shell/prompt, (assuming variable abc wasn't defined in the first place):
    % echo $abc abc: Undefined variable.
    That's because:
    [Parent process] ======> [Perl subprocess] ====> [Sub process shell] Env list #1, Env list #2 Env list #3 "abc" NOT defined copied from the copied from the Parent process, Perl subprocesses, define "abc" here "abc" still defined
    So, when you've set the environment variable abc in the Perl subprocess, it is only altering the copy of the environment list inherited from the parent, not the parent's environment.

    Moral of the story is:  there is no way that you can ever set an environment variable in a subprocess and have it "persist" to the parent process.

    Update:  And the same thing is true, of course, for the process' notion of current directory.


    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
Re: Perl & Cshell
by blazar (Canon) on May 11, 2006 at 14:12 UTC

    The shell executed in system is not csh. Most probably bash. You can directly manipulate %ENV, though: see perldoc perlvar. Also beware of

    perldoc -q environment

    (maybe you knew, maybe you didn't, in doubt better to point this out.)

      Technically, it's more likely that it's /bin/sh - whatever that is. Check perl -MConfig -le 'print $Config{sh}'. On Linux, this is usually bash, but as I recall, bash does some things slightly differently when invoked as sh than as bash, largely for backwards compatability with the Bourne Shell upon which it was based.

      Making /bin/sh a link to csh seems just whacked though. Most of your system won't work properly if you try it.

Re: Perl & Cshell
by derby (Abbot) on May 11, 2006 at 14:04 UTC

    <rant>That's it! As popeye says "I've hads all I can take I can't takes it no more." I'm starting a campaign to downvote everytime this question comes up *plus* every reply. I'm all for helping beginners but come on ... how many times has this question been asked? I completely understand how process concepts trip novices but the question displays a complete lack of initiative -- it's been asked and answered an inordinate amount of times. </rant>

    -derby

    And please ... somebody downvote my reply ..

      In that case maybe the documentation is at fault? (no, I didn't vote you down)