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

时间:2010-06-03 16:09:59

标签: perl unix shell environment-variables

我有一个shell脚本,带有shell变量列表,在进入编程环境之前执行。

我想使用Perl脚本进入编程环境:

system("environment_defaults.sh");
system("obe");

但是当我进入环境时,变量没有设置。

6 个答案:

答案 0 :(得分:9)

当您调用第二个命令时,它不会在您在第一个命令中修改的环境中完成。事实上, 第一个命令没有剩余环境,因为用于调用“environment_defaults.sh”的shell已经退出。

要保留第一个命令的上下文,请在同一个shell中调用它们:

system("source environment_defaults.sh && obe");

请注意,您需要使用source调用shell脚本,以便在当前 shell中执行其操作,而不是调用新的shell来执行它们。

或者,在每个shell的开头修改你的环境(例如使用.bash_profile,如果使用bash),或者在perl中改变你的环境变量:

$ENV{FOO} = "hello";
system('echo $FOO');

答案 1 :(得分:2)

将调用不同的sh -c进程,并在这些进程中隔离环境变量。

同样不调用environment_defaults.sh还会在这些变量将被隔离设置的范围内进行另一个sh进程吗?

或者在导出这些环境变量的情况下启动Perl脚本,这些变量将为其所有子进程设置。

答案 2 :(得分:2)

每个进程都有自己的环境,每次调用“system”时都会运行一个新进程。所以,你正在做的事情是行不通的。您必须在一个进程中运行这两个命令。

但请注意,在Perl脚本存在之后,它在命令行中无法使用它设置的任何环境变量,因为Perl脚本也是一个具有自己环境的进程。

答案 3 :(得分:0)

更新:哦,这不是你要求的,但它可能对某人有用。)

如果安装了GDB,您可以使用以下hack设置/修改父shell变量(为清晰起见,使用非严格样式):

#!/usr/bin/perl
# export.pl

use File::Temp qw( tempfile );

%vars = (
    a => 3,
    b => 'pigs'
);

$ppid = getppid;

my @putvars = map { "call putenv (\"$_=$vars{$_}\")" } keys %vars;

$" = "\n";

$cmds = <<EOF;
attach $ppid
@putvars
detach
quit
EOF

($tmpfh, $tmpfn) = tempfile( UNLINK => 1 );
print $tmpfh $cmds;

`gdb -x $tmpfn`

测试:

$ echo "$a $b"

$ ./export.pl 
$ echo "$a $b"
3 pigs

答案 4 :(得分:0)

但是!可能是!

#!/usr/bin/perl -w

use strict;

my $perldumpenv='perl -MData::Dumper -e '."'".
    '\$Data::Dumper::Terse=1;print Dumper(\%ENV);'."'";

eval '%ENV=('.$1.')' if `bash -c "
        source environment_defaults.sh >/dev/null;
        $perldumpenv"`
    =~ /^\s*\{(.*)\}\s*$/mxs;

system("obe");

一点 overkill ,因为它运行fork到Perl-to-dump环境,但是以安全的方式运行Perl绑定环境而Data::Dumper < / strong>用于发送/存储和检索Perl变量的库。

Nota:这不关心安全注意事项:您必须信任environment_defaults.sh与主Perl脚本相同的级别!!!

答案 5 :(得分:0)

现在可以使用Env::Modify module

完成此操作
use Env::Modify 'source';   # or use Env::Modify qw(source system);
source("environment_defaults.sh");
... environment from  environment_defaults.sh  is now available
... to Perl and to the following 'system' call
system("obe");