can we source a shell script in perl script

匿名 (未验证) 提交于 2019-12-03 09:02:45

问题:

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

Example: Program 1:

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

program 2:

cat test2.sh #!/bin/ksh . ./test1.sh   echo `$DATE` 

Program 3:

cat test3.pl #!/usr/bin/perl ### here I need to source the test1.sh script print `$DATE`' 

How to source the shell in perl to get the date printed when I execute test3.pl

thanks raghu

回答1:

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


回答2:

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"; 


回答3:

You can't source shell files in Perl 5. Sourcing is literally running the commands in the shell file in the target shell; however, it is trivial to open and read the file:

#!/usr/bin/perl  use strict; use warnings;  use Carp;  sub source {     my $file = shift;     open my $fh, "<", $file         or croak "could not open $file: $!";      while (<$fh>) {         chomp;         #FIXME: this regex isn't quite good enough         next unless my ($var, $value) = /\s*(\w+)=([^#]+)/;         $ENV{$var} = $value;     } }  source "./test1.sh";  print "$ENV{DATE}\n"; 


回答4:

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...



回答5:

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.



回答6:

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`; 


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!