Perl system() 调用使用哪个 shell?
Posted
技术标签:
【中文标题】Perl system() 调用使用哪个 shell?【英文标题】:Which shell does a Perl system() call use? 【发布时间】:2011-05-12 15:00:28 【问题描述】:我正在使用系统调用来完成一些任务
system('myframework mycode');
但它抱怨缺少环境变量。 这些环境变量是在我的 bash shell 中设置的(从我运行 Perl 代码的地方)。
我做错了什么?
system
调用是否创建了一个全新的 shell(没有环境变量设置)?我怎样才能避免这种情况?
【问题讨论】:
【参考方案1】:这很复杂。 Perl 不一定调用 shell。 Perldoc 说:
如果只有一个标量参数,则检查参数是否有 shell 元字符,如果有,则将整个参数传递给系统的命令 shell 进行解析(在 Unix 平台上是 /bin/sh -c,但在其他平台上有所不同)。如果参数中没有shell元字符,则将其拆分为单词并直接传递给 execvp ,这样效率更高。
所以实际上看起来你会将参数直接传递给 execvp。此外,shell 是否加载了您的 .bashrc、.profile 或 .bash_profile 取决于 shell 是否是交互式的。可能不是,但您可以查看 this。
【讨论】:
【参考方案2】:如果您不想调用 shell,请使用列表调用 system
:
system 'mycommand', 'arg1', '...';
system qwmycommand arg1 ...;
如果你想要一个特定的 shell,显式调用它:
system "/path/to/mysh -c 'mycommand arg1 ...'";
【讨论】:
【参考方案3】:我认为这不是 shell 选择的问题,因为环境变量总是由子进程继承,除非明确清理。 你确定你已经导出了你的变量吗? 这将起作用:
$ A=5 perl -e 'system(qecho $A);'
5
$
这也可以:
$ export A=5
$ perl -e 'system(qecho $A);'
5
$
这不会:
$ A=5
$ perl -e 'system(qecho $A);'
$
【讨论】:
【参考方案4】:system() 将 /bin/sh 作为 shell 调用。如果您使用的是 ARM 等稍微不同的机器,最好阅读 exec 系列调用的手册页——默认行为。如果需要,您可以调用您的 .profile,因为 system() 需要一个命令
system(" . myhome/me/.profile && /path/to/mycommand")
【讨论】:
【参考方案5】:我为此苦苦挣扎了 2 天。就我而言,环境变量在 linux 下正确设置,但在 cygwin 下没有。
来自mkb's 的答案我想看看man perlrun
,它提到了一个名为PERL5SHELL
的变量(特定于Win32 端口)。然后以下解决了问题:
$ENVPERL5SHELL = "sh";
通常情况下 - 我只能说“它对我有用”,尽管文档确实暗示这可能是一个明智的解决方案:
可以设置为 perl 必须在内部用于执行“反引号”命令或 system() 的替代 shell。
如果 perl 使用的 shell 没有隐式继承环境变量,那么它们不会为你设置。
【讨论】:
【参考方案6】:我弄乱了在this post 上为我的脚本设置的环境变量,我需要设置环境变量$DBUS_SESSION_BUS_ADDRESS,但是当我以root 身份调用脚本时它不会。您可以通读它,但最后您可以检查 %ENV 是否包含您需要的变量,如果没有则添加它们。
来自perlvar
%ENV $ENVexpr 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 $ENVq/MY_ENV_VARIABLE/ . "\n"'
如果这不起作用,那么您需要将其添加到脚本顶部的 %ENV。
【讨论】:
【参考方案7】:在您的系统上尝试system("echo \$SHELL");
。
【讨论】:
这是错误的。system
电话不以任何方式、形状或形式尊重 $SHELL。查看马特凯恩的回答以上是关于Perl system() 调用使用哪个 shell?的主要内容,如果未能解决你的问题,请参考以下文章