如何在Perl脚本中导出一个shellvariables?

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

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

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

但是当我进入环境variables没有设置。

当你调用你的第二个命令时,它不会在你在第一个命令中修改的环境中完成。 实际上,第一个命令没有剩余的环境,因为用来调用“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'); 

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

另外不调用environment_defaults.sh也做了另一个sh进程内的这些变量将独立设置?

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

每个进程都有自己的环境,每次调用“系统”时都会运行一个新进程。 所以,你在做什么都行不通。 您将不得不在一个进程中运行这两个命令。

但是,请注意,在您的Perl脚本存在之后,它所设置的任何环境变量都不会在命令行中提供给您,因为您的Perl脚本也是一个拥有自己的环境的进程。

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

如果安装了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 

但是,是的! 可能是!

 #!/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"); 

有点矫枉过正,因为它运行一个分支到一个只能转换Perl的环境,但以安全的方式运行Perl绑定环境,而Data::Dumper是用来发送/存储和检索Perl变量的库。

注意:这不关心安全考虑: 你必须在主Perl脚本的相同级别信任environment_defaults.sh

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

 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");