2010-11-19 92 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不隱式地繼承環境變量,那麼它們將不會爲您設置。