Perl 代码
`. /home/chronicles/logon.sh `;
print "DATA : $ENV{ID}\n";
在 logon.sh 中,我们正在导出变量“ID”(shell 脚本的来源)。
手动运行
$> . /home/chronicles/logon.sh
$> echo $LOG
当我手动在终端中运行时(而不是从脚本中)。我得到了输出。(但不能从脚本中工作)
我关注了这篇文章:
但没有解决问题。
笔记
我不允许更改“logon.sh”脚本。
Perl 代码
`. /home/chronicles/logon.sh `;
print "DATA : $ENV{ID}\n";
在 logon.sh 中,我们正在导出变量“ID”(shell 脚本的来源)。
手动运行
$> . /home/chronicles/logon.sh
$> echo $LOG
当我手动在终端中运行时(而不是从脚本中)。我得到了输出。(但不能从脚本中工作)
我关注了这篇文章:
但没有解决问题。
笔记
我不允许更改“logon.sh”脚本。
反引号内的脚本在子进程中执行。虽然环境变量是从父进程继承的,但父进程无法访问子进程的环境。
但是,您可以返回子环境变量的内容并将其放入 Perl 变量中,例如
use strict; use warnings; use feature 'say';
my $var = `ID=42; echo \$ID`;
chomp $var;
say "DATA: $var";
输出:
DATA: 42
这是一个示例 shell 会话:
$ cat test_script
echo foo
export test_var=42
$ perl -E'my $cmd = q(test_var=0; . test_script >/dev/null; echo $test_var); my $var = qx($cmd); chomp $var; say "DATA: $var"'
DATA: 42
正常输出被重定向到/dev/null,所以只有echo $test_var显示。
它行不通。
不能从子进程继承环境变量。
环境变量可以在您的“手动运行”中更新,因为它在同一个“bash”进程中。
source 命令只是在当前 shell 下运行 login.sh 中的每个命令。
您可以参考的更多信息:我们可以在 perl 脚本中获取 shell 脚本吗
好吧,我找到了一个对我来说听起来不错的解决方案:这看起来很健壮,因为它使用经过广泛测试的机制将 shell 环境绑定到 perl(运行 perl)和健壮的库以perl 变量语法导出它们以进行重新注入在根 perl 会话中。
该行export COLOR tty对于要求我的 bash 导出更新的变量很有用......这似乎工作正常。
#!/usr/bin/perl -w
my $perldumpenv='perl -MData::Dumper -e '."'".
'\$Data::Dumper::Terse=1;print Dumper(\%ENV);'."'";
eval '%ENV=('.$1.')' if `bash -c "
. ./home/chronicles/logon.sh;
export COLOR tty ID;
$perldumpenv"`
=~ /^\s*\{(.*)\}\s*$/mxs;
# map { printf "%-30s::%s\n",$_,$ENV{$_} } keys %ENV;
printf "%s\n", $ENV{'ID'};
无论如何,如果您无权访问logon.sh,则必须在运行此类解决方案之前信任它。
老的...
这是我的第一篇文章......出于历史目的,不要再看了。
唯一的方法是解析结果命令,同时要求命令转储环境:
my @lines=split("\n",`. /home/chronicles/logon.sh;set`);
map { $ENV{$1}=$2 if /^([^ =])=(.*)$/; } @lines;
您可以执行以下操作:
#/usr/bin/perl
use strict;
use warnings;
chomp(my @values = `. myscript.sh; env`);
foreach my $value (@values) {
my ($k, $v) = split /=/, $value;
$ENV{$k} = $v;
}
foreach my $key (keys %ENV) {
print "$key => $ENV{$key}\n";
}
现在可以使用Env::Modify模块完成
use Env::Modify 'source';
source("/home/chronicles/logon.sh");
... environment setup in logon.sh is now available to Perl ...
你的 Perl 进程是 shell 进程的父进程,所以它不会从它继承环境变量。继承以另一种方式起作用,从父母到孩子。
但是,当您使用反引号运行脚本时,如图所示,脚本的标准输出将返回到 Perl 脚本。因此,要么修改 shell 脚本以您显示的 echo $LOG 语句结束,要么创建一个新的 shell 脚本来运行 login.sh,然后使用 echo $LOG。您的 Perl 脚本将是:
my $value = `./myscript.sh`;
print $value;