Perl system()调用使用哪个shell?

时间:2010-11-19 12:45:23

标签: perl shell system

我正在使用系统调用来执行某些任务

system('myframework mycode');

但它抱怨缺少环境变量。 这些环境变量是在我的bash shell中设置的(从那里我运行Perl代码)。

我做错了什么?

system调用是否会创建一个全新的shell(没有环境变量设置)?我怎么能避免这种情况?

7 个答案:

答案 0 :(得分:18)

这很复杂。 Perl不一定会调用shell。 Perldoc说:

  

如果只有一个标量参数,则检查参数是否为shell元字符,如果有,则将整个参数传递给系统的命令shell进行解析(这是Unix平台上的/ bin / sh -c,但在其他平台上有所不同)。如果参数中没有shell元字符,它将被拆分为单词并直接传递给execvp,这样效率更高。

所以它实际上看起来你会将参数传递给execvp。此外,shell是否加载了.bashrc,.profile或.bash_profile取决于shell是否是交互式的。可能不是,但你可以检查this

答案 1 :(得分:4)

如果您不想调用shell,请使用列表调用system

system 'mycommand', 'arg1', '...';
system qw{mycommand arg1 ...};

如果您需要特定的shell,请明确调用它:

system "/path/to/mysh -c 'mycommand arg1 ...'";

答案 2 :(得分:4)

我认为这不是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});'

$

答案 3 :(得分:3)

system()将/ bin / sh作为shell调用。如果你在一个像ARM这样有点不同的盒子上,最好阅读exec系列调用的手册页 - 默认行为。如果需要,可以调用.profile,因为system()接受命令

system(" . myhome/me/.profile && /path/to/mycommand")

答案 4 :(得分:3)

我努力工作了2天。在我的例子中,环境变量在linux下正确设置但不是cygwin。

mkb's回答我想查看man perlrun,它提到了一个名为PERL5SHELL的变量。接下来解决了这个问题:

$ENV{PERL5SHELL} = "sh";

通常情况如此 - 我真正可以说的是“它对我有用”,尽管文档确实暗示这可能是一个明智的解决方案:

  

可以设置为perl必须在内部用于执行“反引号”命令或system()的替代shell。

如果perl使用的shell没有隐式继承环境变量,那么就不会为你设置它们。

答案 5 :(得分:1)

我在this post上为我的脚本设置了环境变量,我需要设置env变量$ 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下运行脚本并且没有保留我的所有用户的env变量,你是在sudo下运行脚本还是像其他用户一样运行,比如www-data(apache)?

简单测试:

user@host:~$ perl -e 'print $ENV{q/MY_ENV_VARIABLE/} . "\n"'

如果这不起作用,则需要将其添加到脚本顶部的%ENV。

答案 6 :(得分:0)

在您的系统上尝试system("echo \$SHELL");