in reply to Re: system ( "source $script" )
in thread system ( "source $script" )

Hold on, that doesn't seem to work. The environment as seen by the perl script is unaffected.

setter.sh:

#!/bin/sh
export VAR=SET

script.pl:

#!/usr/bin/perl
system ( ". ./setter.sh" );
print "VAR=$ENV{VAR}\n";

This gives me VAR= and was hoping for VAR=SET

Replies are listed 'Best First'.
Re^3: system ( "source $script" )
by Anonyrnous Monk (Hermit) on Jan 28, 2011 at 21:44 UTC

    This is not what I said.

    You need to print the environment from within the new shell started by system() — e.g. with env, as shown.  (But nothing keeps you from using Perl code to print out the environment, in case you don't like env's output:  system ". $script && ./my_env_prettyprinter.pl" )

    As soon as system() returns, the shell has terminated, and the new environment is gone with it. You cannot have a subshell set environment variables in a parent process, such as your Perl script, or the shell the Perl script has been started from, etc.

      Sorry, I misunderstood. Does perl have something analogous to the shell's source? I'd like to apply the initialization scripts to the shell which the Perl script is running in.

        Does perl have something analogous to the shell's source?

        Not for shell code, as shell code needs to be interpreted by a shell (likewise, a shell cannot run Perl code).

        As for "the shell which the Perl script is running in", Perl is started from a shell, but it's a separate subprocess, so strictyl speaking, the Perl script is not running "in" a shell.  This means the same child-parent restrictions apply, i.e. the Perl script (nor any further child processes started from it) cannot set the environment of its parent shell.

        Update: maybe this clarifies it somewhat. When you run something from the command line, for example

        $ perl -e 'system "ps Tf ; sleep 1"'

        you see child-parent relationships as follows (indenting means "child of")

        PID TTY STAT TIME COMMAND 29353 pts/7 S 0:00 bash # th +e initial interactive command shell 29388 pts/7 S+ 0:00 \_ perl -e system "ps Tf ; sleep 1" # yo +ur Perl script 29389 pts/7 S+ 0:00 \_ sh -c ps Tf ; sleep 1 # a +shell started by system() 29390 pts/7 R+ 0:00 \_ ps Tf # a +subprocess run by the shell

        All those are separate processes created via fork/exec, and no child is able to manipulate the environment of its respective parent process. But it does inherit the environment of its parent.

        Does perl have something analogous to the shell's source?
        Yes. It's called do. But, just as the shell's source, it only applies to the current process.
        I'd like to apply the initialization scripts to the shell which the Perl script is running in.
        Then you have to do it from within that shell. Trust me, you really, really do not want an environment where any program you can start can rearrange your environment.

        I'd like to apply the initialization scripts to the shell which the Perl script is running in.
        Note that it's possible to run a perl process from another (non-shell) process without invoking an intermediary shell.

        As for setting an environment variable inside a program or script and have that change affect the parent shell, that's a FAQ, both a Unix FAQ and a Perl one (see perlfaq8). See also: export environment variable from a perl program.