can we source a shell script in perl script

前端 未结 7 751
隐瞒了意图╮
隐瞒了意图╮ 2021-01-15 04:54

can we source a shell script in the perl script??

Example: Program 1:

cat test1.sh
#!/bin/ksh
DATE=/bin/date

program 2:

<         


        
相关标签:
7条回答
  • 2021-01-15 05:17

    I met a close need from the OP's in a project, where I needed to configure a Perl script (it could be any language, for that matter) by sourcing a shell script defining the environment.

    I personally rarely use sourcing for anything else than configuration and environment setting (the only other good reason for sourcing I am aware of, is for importing functions in shell scripts, but I may be missing some creative usage).

    My solution was to source the configuration script from a launcher script (in shell), and then to exec the Perl script in the same launcher script (replacing effectively the launcher script by the Perl script, thus avoiding to create a subprocess).

    # configuration_script.sh
    export MY_ENV_VAR1=value1
    export MY_ENV_VAR2=value2
    
    # launcher_script.sh
    . configuration_script.sh # source the configuration
    exec /path/to/main_script.pl "$@" # could be any other language here (Python, Tcl, Ruby, C, Java...)
    

    The "$@" allows to pass the command line arguments from the launcher script to the main script.

    It's then up to the main script author to retrieve the environment (e.g. with $ENV{MY_ENV_VAR1} in Perl).

    0 讨论(0)
  • 2021-01-15 05:21

    You cannot do a

    system("source src.sh");
    

    system() starts a new sub-shell, your environment variables do not get passed to the shell your Perl script is running in. Even though your shell script exports variables, it will export them to the sub-shell, not to your actual shell.

    One solution would be to write a wrapper script which

    1. First sources the shell script and then
    2. Runs the Perl script
    0 讨论(0)
  • 2021-01-15 05:24

    Yes, you can now do this with the Env::Modify module.

    use Env::Modify qw(:ksh source);
    source("./test1.sh");     # env settings from test1.sh now available in Perl
    print `$ENV{DATE}`;       # print `/bin/date`;
    
    0 讨论(0)
  • 2021-01-15 05:28

    You can do something simple, like this:

    system "source /path/to/shell_env.sh &&"
         . "/path/to/script.sh";
    

    NOTE that this is different than the following which is not recommended:

       system "source /path/to/shell_env.sh &&"
            . "/bin/sh /path/to/script.sh";
    
    0 讨论(0)
  • 2021-01-15 05:30

    I don't know that this will help, but I felt compelled to come up with a way to write this in Perl. My intent was to have Perl run a shell script, and to assign any shell variables it sets to like-named variables in the Perl script.

    The others are correct in that any shell script you "source" is going to be in a sub-shell. I figured I could use "sh -x cmd" to at least have the shell show the variables as they're set.

    Here's what I wrote:

    use strict;  use warnings;
    
    our $DATE;
    
    my $sh_script = "./test1.sh";
    
    my $fh;
    open($fh, "sh -x '$sh_script' 2>&1 1>/dev/null |") or die "open: $!";
    foreach my $line (<$fh>) {
        my ($name, $val);
        if ($line =~ /^\+ (\w+)='(.+)'$/) {  # Parse "+ DATE='/bin/date;'
            $name = $1;
            ($val = $2) =~ s{'\\''}{'}g;  # handle escaped single-quotes (eg. "+ VAR='one'\''two'")
        } elsif ($line =~ /^\+ (\w+)=(\S+)$/) {  # Parse "+ DATE=/bin/date"
            $name = $1;
            $val = $2;
        } else {
            next;
        }
        print "Setting '$name' to '$val'\n" if (1);
        # NOTE: It'd be better to use something like "$shell_vars{$name} = $val",
        #  but this does what was asked (ie. $DATE = "/bin/date")...
        no strict 'refs';
        ${$name} = $val;    # assign to like-named variable in Perl
    }
    close($fh) or die "close: ", $! ? $! : "Exit status $?";
    
    print "DATE: ", `$DATE` if defined($DATE);
    

    There's certainly more error-checking you could do, but this did the trick for me if all you want to catch is shell variables.

    0 讨论(0)
  • 2021-01-15 05:30

    Uhm.. is the below cheating?

    #!/bin/sh
    . ./test1.sh # source the test script
    echo Bash says $DATE
    export DATE;      # KEY to have the below Perl bit see $ENV{DATE}
    perl <<'ENDPERL';
        print "Perl says $ENV{DATE}\n";
    ENDPERL
    

    The problem is that sourcing the sh file may do whatever, and not just assign value X to variable Y...

    0 讨论(0)
提交回复
热议问题