我有一个shell脚本,带有shell变量列表,在进入编程环境之前执行。
我想使用Perl脚本进入编程环境:
system("environment_defaults.sh");
system("obe");
但是当我进入环境时,变量没有设置。
答案 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");