2010-11-19 87 views
8

我使用一个系统调用来完成一些任务Perl系统()调用使用哪个shell?

system('myframework mycode'); 

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

我在做什么错?

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

回答

17

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

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

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

3

system()调用/ bin/sh作为shell。如果你使用的是像ARM这样有些不同的盒子,那么阅读exec系列调用的手册页是很好的 - 默认行为。你可以调用你的.profile文件,如果你需要,因为系统()接受命令

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

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

+1

这是错误的。 'system'调用不会以任何方式,形状或形式尊重$ SHELL。看到马特凯恩的答案 – DVK 2010-11-19 14:23:31

3

如果你不想调用一个shell,调用system与列表:

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

如果你想有一个特定的外壳,显式调用:

system "/path/to/mysh -c 'mycommand arg1 ...'"; 
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});' 

$ 
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)?

简单的测试:

[email protected]:~$ perl -e 'print $ENV{q/MY_ENV_VARIABLE/} . "\n"' 

,如果不工作,那么你就需要把它在你的脚本的顶部添加到%ENV。

2

我一直在努力工作2天。在我的情况下,环境变量在linux下正确设置,但不是cygwin。

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

$ENV{PERL5SHELL} = "sh"; 

如经常的情况 - 所有我真的可以说是“我的作品”,虽然文件并暗示这可能是一个明智的解决办法:

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

如果perl使用的shell不隐式地继承环境变量,那么它们将不会为您设置。