6

我正在尝试LD_LIBRARY_PATH通过 Perl 脚本以下列方式设置环境变量 :

.profile在下创建/root

.profile有一个export命令说:

export LD_LIBRARY_PATH=/

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

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

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

我究竟做错了什么?

4

5 回答 5

12

Your current script doesn't even change an environment variable in the Perl script itself. Rather, it invokes a shell as a subprocess; that shell process executes . /root/.profile, which updates $LD_LIBRARY_PATH only in that shell process.

You can change an environment variable in a Perl script (more precisely, in the process running the Perl script) by updating %ENV:

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

As perldoc -v %ENV says:

%ENV The hash %ENV contains your current environment. Setting a value in "ENV" changes the environment for any child processes you subsequently "fork()" off.

But that probably still won't do what you want; it won't (and can't) affect the environment of the process that invokes the Perl script (your interactive shell), only the Perl process itself and anything it invokes.

I'll assume you want to update $LD_LIBRARY_PATH in your current interactive shell process. To do that, you can have you Perl script print a shell command that will update $LD_LIBRARY_PATH. Then, rather than simply running your Perl script, you can execute it and then evaluate its output. For example:

$ 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 
/
$ 

This assumes that your current shell is bash or something similar.

Another option: After modifying %ENV, your Perl script can invoke another command, even a new interactive shell. The new process will inherit its environment from the Perl script. This can be a bit cumbersome, though; for example, if the new process is an interactive shell, it won't inherit unexported variables or history from the parent shell.

(One note, not directly related to your question: The fact that you're messing with /root/.profile implies that you're doing things as root (superuser). This can be dangerous. Use the root account (either by logging into it or via sudo only for things that actually need root privileges. For anything else, use a personal user account.

于 2013-10-05T00:44:25.457 回答
5

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

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

如果您想编写一个由 shell 用来更改其环境的程序,通常这样做的方式是让脚本将 shell 命令写入标准输出。然后,shell 使用命令替换执行此操作并用于eval执行生成的命令:

Perl 脚本:

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

外壳脚本:

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

有关以这种方式工作的命令示例,请参阅tsetssh-agent

于 2013-10-05T00:38:37.230 回答
5

system启动一个新进程,并且更改那里的环境不会影响脚本进程中的环境(通常-通常有依赖于操作系统的方法来更改其他进程的环境)。

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

$ENV{LD_LIBRARY_PATH} = '/';
于 2013-10-05T00:39:38.930 回答
3

现在可以使用Env::Modify模块来完成:

use Env::Modify 'source';
source("/root/.profile");
... env settings of .profile are now available to Perl ...
于 2017-01-30T16:26:47.080 回答
1

你不能这样做。

这是来自Perl 常见问题解答

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

于 2013-10-05T01:45:17.130 回答