我创建了一个调用两个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脚本的情况下做到这一点?
答案 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`;
中找到实际说明
答案 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")