Linux 通过 Perl 脚本设置环境变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19192682/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Setting an environment variable through a Perl script
提问by user2848437
I am trying to set an environment variable, LD_LIBRARY_PATH
, through a Perl script in the following way:
我正在尝试LD_LIBRARY_PATH
通过以下方式通过 Perl 脚本设置环境变量:
I have created .profile
under /root
我创建了.profile
下/root
.profile
has an export
command say:
.profile
有一个export
命令说:
export LD_LIBRARY_PATH=/
My Perl script is test.pl
and it has:
我的 Perl 脚本是test.pl
,它有:
#!/usr/bin/perl
system(". /root/.profile");
When I execute ./test.pl
, LD_LIBRARY_PATH
doesn't change.
当我执行时./test.pl
,LD_LIBRARY_PATH
不会改变。
What am I doing wrong?
我究竟做错了什么?
回答by Barmar
To change the environment in a Perl script, assign to the %ENV
hash:
要更改 Perl 脚本中的环境,请分配给%ENV
散列:
$ENV{'LD_LIBRARY_PATH'} = '/';
If you want to write a program that's used by a shell to change its environment, the way this is generally done is to have the script write shell commands to stdout. The shell then executes this with command substitution and uses eval
to execute the resulting commands:
如果您想编写一个 shell 用来改变其环境的程序,通常这样做的方法是让脚本将 shell 命令写入 stdout。然后 shell 使用命令替换eval
来执行它,并使用它来执行生成的命令:
Perl script:
Perl 脚本:
#!/usr/bin/perl
print 'LD_LIBRARY_PATH=\n';
Shell script:
外壳脚本:
eval "$(/path/to/perlscript)"
For examples of commands that work like this, see tset
and ssh-agent
.
回答by muhmuhten
system
starts a new process, and changing the environment there won't affect the environment in the process of your script (usually—there are generally os-dependent means of changing other processes' environments).
system
启动一个新进程,改变那里的环境不会影响脚本进程中的环境(通常——通常有依赖于操作系统的方法来改变其他进程的环境)。
The environment in a perl program is associated with %ENV
, which is kind of like (it isn't actually) a tied hash to the environment: changing it will change the environment. Thus:
perl 程序中的环境与 相关联%ENV
,这有点像(实际上不是)与环境相关联的散列:改变它会改变环境。因此:
$ENV{LD_LIBRARY_PATH} = '/';
回答by Keith Thompson
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.
您当前的脚本甚至不会更改 Perl 脚本本身中的环境变量。相反,它调用一个 shell 作为一个子进程;该 shell 进程执行. /root/.profile
,$LD_LIBRARY_PATH
仅在该 shell 进程中更新。
You can change an environment variable in a Perl script (more precisely, in the process running the Perl script) by updating %ENV
:
您可以通过更新%ENV
以下内容来更改 Perl 脚本中的环境变量(更准确地说,是在运行 Perl 脚本的过程中):
$ENV{LD_LIBRARY_PATH} = '/'; # or some more reasonable value
As perldoc -v %ENV
says:
正如perldoc -v %ENV
所说:
%ENV
The hash%ENV
contains your current environment. Setting a value in "ENV" changes the environment for any child processes you subsequently "fork()
" off.
%ENV
散列%ENV
包含您当前的环境。在“ENV”中设置一个值会更改您随后fork()
“关闭”的任何子进程的环境。
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.
但这可能仍然无法满足您的要求;它不会(也不能)影响调用 Perl 脚本(您的交互式 shell)的进程的环境,只会影响 Perl 进程本身及其调用的任何内容。
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 commandthat will update $LD_LIBRARY_PATH
. Then, rather than simply running your Perl script, you can execute it and then evaluate its output. For example:
我假设您想$LD_LIBRARY_PATH
在当前的交互式 shell 进程中进行更新。为此,您可以让 Perl 脚本打印一个 shell 命令,该命令将更新$LD_LIBRARY_PATH
. 然后,您可以执行它然后评估它的输出,而不是简单地运行 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
/
$
This assumes that your current shell is bash or something similar.
这假设您当前的 shell 是 bash 或类似的东西。
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 unexportedvariables or history from the parent shell.
另一种选择:修改后%ENV
,您的 Perl 脚本可以调用另一个命令,甚至是一个新的交互式 shell。新进程将从 Perl 脚本继承其环境。不过,这可能有点麻烦;例如,如果新进程是一个交互式 shell,它不会从父 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.
(一个注释,与您的问题没有直接关系:您搞乱的事实/root/.profile
意味着您正在以root
(超级用户)身份做事。这可能很危险。使用该root
帐户(通过登录或sudo
仅用于事物这实际上需要 root 权限。对于其他任何事情,请使用个人用户帐户。
回答by Andy Lester
You can't do it.
你不能这样做。
This is from the Perl FAQ:
这是来自Perl 常见问题解答:
In the strictest sense, it can't be done--the script executes as a different process from the shell it was started from. Changes to a process are not reflected in its parent--only in any children created after the change. There is shell magic that may allow you to fake it by eval()ing the script's output in your shell; check out the comp.unix.questions FAQ for details.
从最严格的意义上讲,这是不可能的——脚本作为一个与它启动的 shell 不同的进程来执行。对进程的更改不会反映在其父进程中——只会反映在更改后创建的任何子进程中。有 shell 魔法可以让你通过在你的 shell 中 eval()ing 脚本的输出来伪造它;有关详细信息,请查看 comp.unix.questions 常见问题解答。
回答by mob
This can now be done with the Env::Modify
module:
这现在可以通过Env::Modify
模块来完成:
use Env::Modify 'source';
source("/root/.profile");
... env settings of .profile are now available to Perl ...