我试图通过以下方式通过Perl脚本设置环境变量LD_LIBRARY_PATH
:
我在.profile
/root
.profile
有export
命令说:
export LD_LIBRARY_PATH=/
我的Perl脚本是test.pl
,它有:
#!/usr/bin/perl
system(". /root/.profile");
当我执行./test.pl
时,LD_LIBRARY_PATH
不会改变。
我做错了什么?
答案 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)"
答案 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常见问题解答。