1

Perl 代码

`. /home/chronicles/logon.sh `; 

print "DATA  : $ENV{ID}\n";

在 logon.sh 中,我们正在导出变量“ID”(shell 脚本的来源)。

手动运行

$> . /home/chronicles/logon.sh
$> echo $LOG

当我手动在终端中运行时(而不是从脚本中)。我得到了输出。(但不能从脚本中工作)

我关注了这篇文章:

如何在 Perl 脚本中导出 shell 变量?

但没有解决问题。

笔记

我不允许更改“logon.sh”脚本。

4

6 回答 6

2

反引号内的脚本在子进程中执行。虽然环境变量是从进程继承的,但父进程无法访问子进程的环境。

但是,您可以返回子环境变量的内容并将其放入 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显示。

于 2012-12-28T14:37:02.913 回答
1

它行不通。

不能从子进程继承环境变量。

环境变量可以在您的“手动运行”中更新,因为它在同一个“bash”进程中。

source 命令只是在当前 shell 下运行 login.sh 中的每个命令。

您可以参考的更多信息:我们可以在 perl 脚本中获取 shell 脚本吗

于 2012-12-28T14:34:08.417 回答
1

好吧,我找到了一个对我来说听起来不错的解决方案:这看起来很健壮,因为它使用经过广泛测试的机制将 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;
于 2012-12-28T15:03:43.420 回答
1

您可以执行以下操作:

#/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";
}
于 2012-12-28T15:40:54.677 回答
1

现在可以使用Env::Modify模块完成

use Env::Modify 'source';
source("/home/chronicles/logon.sh");
... environment setup in logon.sh is now available to Perl ...
于 2017-01-30T16:20:29.397 回答
0

你的 Perl 进程是 shell 进程的父进程,所以它不会从它继承环境变量。继承以另一种方式起作用,从父母到孩子。

但是,当您使用反引号运行脚本时,如图所示,脚本的标准输出将返回到 Perl 脚本。因此,要么修改 shell 脚本以您显示的 echo $LOG 语句结束,要么创建一个新的 shell 脚本来运行 login.sh,然后使用 echo $LOG。您的 Perl 脚本将是:

my $value = `./myscript.sh`;
print $value;
于 2012-12-28T14:40:27.357 回答