【发布时间】:2011-02-27 09:46:34
【问题描述】:
我有一个 shell 脚本,其中包含一个 shell 变量列表,在进入编程环境之前执行。
我想用Perl脚本进入编程环境:
system("environment_defaults.sh");
system("obe");
但是当我进入环境时,变量并没有设置。
【问题讨论】:
标签: perl unix shell environment-variables
我有一个 shell 脚本,其中包含一个 shell 变量列表,在进入编程环境之前执行。
我想用Perl脚本进入编程环境:
system("environment_defaults.sh");
system("obe");
但是当我进入环境时,变量并没有设置。
【问题讨论】:
标签: perl unix shell environment-variables
不同的sh -c 进程将被调用并且环境变量在这些进程中被隔离。
调用 environment_defaults.sh 也不会在这些变量将被单独设置为的范围内创建另一个 sh 进程吗?
或者在导出这些环境变量的情况下启动 Perl 脚本,然后为其所有子进程设置这些变量。
【讨论】:
当您调用第二个命令时,它并没有在您在第一个命令中修改的环境中完成。事实上,没有第一个命令留下的环境,因为用来调用“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');
【讨论】:
每个进程都有自己的环境,每次调用“系统”时,它都会运行一个新进程。所以,你正在做的事情是行不通的。您必须在一个进程中运行这两个命令。
但是请注意,在您的 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-only-to-dump 环境的分支,但是以安全的方式运行 Perl 绑定环境并且Data::Dumper 是 > 用于发送/存储和检索 Perl 变量的库。
注意:这不关心安全问题:你必须信任environment_defaults.sh 与主 Perl 脚本处于同一级别!!!
【讨论】:
现在可以使用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");
【讨论】: