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

5

我有一个 shell 脚本,其中包含一系列的 shell 变量,在进入编程环境之前会执行该脚本。

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

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

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

5个回答

9

当您调用第二个命令时,它不是在您修改第一个命令的环境中执行的。事实上,来自第一个命令的任何环境都不存在了,因为用于调用“environment_defaults.sh”的shell已经退出。

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

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

请注意,为了在当前shell中执行其操作,而不是调用一个新的shell来执行它们,您需要使用source调用shell脚本。
或者,在每个shell开头修改您的环境(例如,使用bash时使用.bash_profile),或在perl本身中进行环境变量更改。
$ENV{FOO} = "hello";
system('echo $FOO');

这不起作用,因为environment_defaults.sh将创建自己的子实例。 - Imre L
谢谢,我会尝试第一个选项。另外两个选项是我想避免的。 - lamcro
@Imre:如果只是执行脚本,将会调用一个新的 shell。使用“source”在同一 shell 中执行命令(答案已更新)。 - Ether
也许你的意思是:system("sh -c 'source environment_defaults.sh; obe'") - Grant McLean

2
不同的 sh -c 进程将被调用,环境变量在其中被隔离。
此外,调用 environment_defaults.sh 也会在其中创建另一个sh进程,在这个进程中变量将被隔离设置?
或者使用这些导出的环境变量启动Perl脚本,并且这些变量将为其所有子进程设置。

2
每个进程都有自己的环境,每次调用“system”时都会运行一个新进程。所以,你正在做的事情不起作用。你必须在单个进程中运行这两个命令。
但是请注意,在你的Perl脚本退出后,它设置的任何环境变量将不可用于命令行,因为你的Perl脚本也是具有自己环境的进程。

0

现在可以使用 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");

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

(基于有没有办法更改另一个进程的环境变量?)请问是否有办法更改另一个进程的环境变量?这个问题在操作系统编程中经常会遇到。如果您知道如何实现,请分享一下您的方法。谢谢! - mykhal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接