【发布时间】:2011-05-12 15:00:28
【问题描述】:
我正在使用系统调用来完成一些任务
system('myframework mycode');
但它抱怨缺少环境变量。 这些环境变量是在我的 bash shell 中设置的(从我运行 Perl 代码的地方)。
我做错了什么?
system 调用是否创建了一个全新的 shell(没有环境变量设置)?我怎样才能避免这种情况?
【问题讨论】:
我正在使用系统调用来完成一些任务
system('myframework mycode');
但它抱怨缺少环境变量。 这些环境变量是在我的 bash shell 中设置的(从我运行 Perl 代码的地方)。
我做错了什么?
system 调用是否创建了一个全新的 shell(没有环境变量设置)?我怎样才能避免这种情况?
【问题讨论】:
如果您不想调用 shell,请使用列表调用 system:
system 'mycommand', 'arg1', '...';
system qw{mycommand arg1 ...};
如果你想要一个特定的 shell,显式调用它:
system "/path/to/mysh -c 'mycommand arg1 ...'";
【讨论】:
我认为这不是 shell 选择的问题,因为环境变量总是由子进程继承,除非明确清理。 你确定你已经导出了你的变量吗? 这将起作用:
$ A=5 perl -e 'system(q{echo $A});'
5
$
这也可以:
$ export A=5
$ perl -e 'system(q{echo $A});'
5
$
这不会:
$ A=5
$ perl -e 'system(q{echo $A});'
$
【讨论】:
system() 将 /bin/sh 作为 shell 调用。如果您使用的是 ARM 等稍微不同的机器,最好阅读 exec 系列调用的手册页——默认行为。如果需要,您可以调用您的 .profile,因为 system() 需要一个命令
system(" . myhome/me/.profile && /path/to/mycommand")
【讨论】:
我为此苦苦挣扎了 2 天。就我而言,环境变量在 linux 下正确设置,但在 cygwin 下没有。
来自mkb's 的答案我想看看man perlrun,它提到了一个名为PERL5SHELL 的变量(特定于Win32 端口)。然后以下解决了问题:
$ENV{PERL5SHELL} = "sh";
通常情况下 - 我只能说“它对我有用”,尽管文档确实暗示这可能是一个明智的解决方案:
可以设置为 perl 必须在内部用于执行“反引号”命令或 system() 的替代 shell。
如果 perl 使用的 shell 没有隐式继承环境变量,那么它们不会为你设置。
【讨论】:
我弄乱了在this post 上为我的脚本设置的环境变量,我需要设置环境变量$DBUS_SESSION_BUS_ADDRESS,但是当我以root 身份调用脚本时它不会。您可以通读它,但最后您可以检查 %ENV 是否包含您需要的变量,如果没有则添加它们。
来自perlvar
%ENV $ENV{expr} The hash %ENV contains your current environment. Setting a value in "ENV" changes the environment for any child processes you subsequently fork() off.
我的问题是我在 sudo 下运行脚本并且没有保留我所有用户的环境变量,您是在 sudo 下运行脚本还是作为其他用户运行脚本,比如 www-data (apache)?
简单测试:
user@host:~$ perl -e 'print $ENV{q/MY_ENV_VARIABLE/} . "\n"'
如果这不起作用,那么您需要将其添加到脚本顶部的 %ENV。
【讨论】:
在您的系统上尝试system("echo \$SHELL");。
【讨论】:
system 电话不以任何方式、形状或形式尊重 $SHELL。查看马特凯恩的回答