Perl在不同的bash脚本中设置并获取env

时间:2015-08-11 06:09:33

标签: linux bash perl shell unix

我创建了一个调用两个bash脚本的perl脚本。第一个脚本将设置一个环境变量,第二个脚本将回显环境变量。我已经给出了文件的内容

# perlscript.pl

print `. setnameenv.sh`;
print `. getnameenv.sh`;
# setnameenv.sh

export my_msg='hello world!'
# getnameenv.sh

echo $my_msg

现在当我运行perl脚本perl perlscript.pl时,我期待着'#hello world'要在屏幕上打印,但实际上我没有看到任何输出。我有没有办法在不修改bash脚本的情况下做到这一点?

5 个答案:

答案 0 :(得分:3)

您可以将perl嵌入到bash脚本中,

#!/bin/bash
. setnameenv.sh
exec perl -x "$0" "$@"

#!perl
# your script below

print `. getnameenv.sh`;

来自perldoc

  

-x   -xdirectory   告诉Perl该程序嵌入了大量不相关的文本中,例如邮件消息中。领先的垃圾将被丢弃,直到以#开头的第一行!并包含字符串“perl”。将应用该行上任何有意义的开关。

答案 1 :(得分:1)

您生成一个shell,执行一些命令来改变它的环境,然后退出shell。在退出shell之前,您从未使用过您创建的环境变量。如果您希望perl看到它,则必须从该shell启动Perl。

. setnameenv.sh ; perlscript.pl

如果您无法更改perlscript.pl的启动方式,您可以选择几个选项,其中没有一个是友好的。其中一个选项是bootstrap。

BEGIN {
   if (!length($ENV{my_msg})) {
      require String::ShellQuote;
      my $cmd = join(' ; ',
         '. setnameenv.sh',
         String::ShellQuote::shell_quote($^X, $0, @ARGV),
      );
      exec($cmd)
         or die $!;
   }
}

答案 2 :(得分:0)

子进程可以继承父进程但不能进行任何更改。同样,父母也无法访问孩子的环境。因此,为了捕捉父母的孩子的环境,孩子应该打印下面的代码所示的值。以下代码也将设置已存在的环境变量,但这可以进行优化

# perlscript.pl

my $env_val = `. setnameenv.sh; env`;
my @env_list = split "\n", $env_str;

foreach (@env_list)
{
   /([\w_]+)=(.*)/;
   $ENV{$1} = $2;
}

print `. getnameenv.sh`;

在此SO answer

中找到实际说明

答案 3 :(得分:0)

仅为子进程导出变量。

您无法将变量导出回父进程。

您需要另一种方式将变量传回父亲或兄弟。

例如,这是一个保存所有导出变量并从文件中读取的示例:

#!/bin/dash
# setnameenv.sh

export my_msg='hello world!'

export > savedVariables.sh

#!/bin/dash
# getnameenv.sh

. ./savedVariables.sh

echo "$my_msg"

注意:这适用于破折号。 bash生成一条他无法回读的行。

答案 4 :(得分:0)

现在可以使用Env::Modify module在Perl中完成此操作。

use Env::Modify qw(source);

source("setnameenv.sh");
# env settings from setnameenv.sh are now available to Perl
# and to the following  system  call

print `. getenvname.sh`;   # or source again, like source("getenvname.sh")