通过Perl脚本设置环境变量

时间:2013-10-05 00:26:38

标签: linux perl bash sh

我试图通过以下方式通过Perl脚本设置环境变量LD_LIBRARY_PATH

我在.profile

下创建了/root

.profileexport命令说:

export LD_LIBRARY_PATH=/

我的Perl脚本是test.pl,它有:

#!/usr/bin/perl
system(". /root/.profile");

当我执行./test.pl时,LD_LIBRARY_PATH不会改变。

我做错了什么?

5 个答案:

答案 0 :(得分:11)

您当前的脚本甚至不会更改Perl脚本本身的环境变量。相反,它调用shell作为子进程;该shell进程执行. /root/.profile,仅在该shell进程中更新$LD_LIBRARY_PATH

您可以通过更新%ENV来更改Perl脚本中的环境变量(更确切地说,在运行Perl脚本的过程中):

$ENV{LD_LIBRARY_PATH} = '/'; # or some more reasonable value

正如perldoc -v %ENV所说:

  

%ENV哈希%ENV包含您当前的环境。在“ENV”中设置值会更改随后“fork()”关闭的任何子进程的环境。

但那可能仍然不会做你想要的;它不会(也不会)影响调用Perl脚本(您的交互式shell)的进程的环境,只会影响Perl进程本身及其调用的任何内容。

我假设您要在当前的交互式shell进程中更新$LD_LIBRARY_PATH。为此,您可以让Perl脚本打印将更新$LD_LIBRARY_PATH的shell命令。然后,您可以执行它,然后评估其输出,而不是简单地运行Perl脚本。例如:

$ cat env.pl
#!/usr/bin/perl

use strict;
use warnings;

print "export LD_LIBRARY_PATH=/\n";
$ ./env.pl          # just prints the command without executing it
export LD_LIBRARY_PATH=/
$ eval $(./env.pl)  # executes the command in the current shell
$ echo $LD_LIBRARY_PATH 
/
$ 

这假设您当前的shell是bash或类似的东西。

另一个选项:修改%ENV后,您的Perl脚本可以调用另一个命令,甚至是新的交互式shell。新进程将从Perl脚本继承其环境。但这可能有点麻烦;例如,如果新进程是交互式shell,则它不会从父shell继承未导出的变量或历史记录。

(请注意,与您的问题没有直接关系:您正在弄乱/root/.profile这一事实意味着您正在执行root(超级用户)。这可能很危险。 root帐户(通过登录或通过sudo仅限实际需要root权限的内容。除此之外,请使用个人用户帐户。

答案 1 :(得分:5)

system启动一个新进程,在那里更改环境不会影响脚本进程中的环境(通常 - 通常是依赖于os的方法来更改其他进程的环境)。

perl程序中的环境与%ENV相关联,这有点像(实际上并非)环境的绑定哈希:更改环境会改变环境。因此:

$ENV{LD_LIBRARY_PATH} = '/';

答案 2 :(得分:3)

要更改Perl脚本中的环境,请分配%ENV哈希:

$ENV{'LD_LIBRARY_PATH'} = '/';

如果要编写shell使用的程序来更改其环境,通常这样做的方法是让脚本将shell命令写入stdout。然后shell使用命令替换执行此操作,并使用eval执行生成的命令:

Perl脚本:

#!/usr/bin/perl
print 'LD_LIBRARY_PATH=\n';

Shell脚本:

eval "$(/path/to/perlscript)"

有关这样工作的命令示例,请参阅tsetssh-agent

答案 3 :(得分:2)

现在可以使用Env::Modify module

完成此操作
use Env::Modify 'source';
source("/root/.profile");
... env settings of .profile are now available to Perl ...

答案 4 :(得分:1)

你不能这样做。

这是the Perl FAQ

  

从最严格的意义上说,它无法完成 - 脚本作为一个与它从它启动的shell不同的进程执行。对进程的更改不会反映在其父进程中 - 仅在更改后创建的任何子进程中。有一些shell魔法可能允许你通过eval()在shell中输出脚本的输出来伪造它;有关详细信息,请查看comp.unix.questions常见问题解答。