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

I'm writing a script that is an "environment setter." After a bunch of messing around, I've settled on a reasonable (though not quite what I'd really like) solution where the script prints a series of "source /path/to/init.sh; source /another/init.sh" commands. The user can either invoke the script with eval "`./Script.pl`", or copy/paste/execute the stuff that gets printed.

I'd like to implement an option where the user could see what the result of sourcing all of the init files would be. I thought it would be nice if I could simply source them for the shell in which the script is running. That way I could print the values and exit, leaving the parent shell unaffected. Is this possible?

Replies are listed 'Best First'.
Re: system ( "source $script" )
by Anonyrnous Monk (Hermit) on Jan 28, 2011 at 21:07 UTC
    I'd like to implement an option where the user could see what the result of sourcing all of the init files would be.

    Maybe something like this:

    system ". $script && env | sort";

    This would run a new shell, source the $script, and print the resulting environment. As it's a new shell, it wouldn't affect the parent shell (as desired).

    (If you want a shell other than what 'perl -V:sh' reports (i.e. what Perl is using by default), you have to run it explicitly, e.g. system "/bin/tcsh", "-c", "shell code here...";)

      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

        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.