exec
函式執行系統指令 且永不返回;如果您希望指令返回,請使用 system
取代 exec
。只有在指令不存在 且 透過系統指令殼層而非直接執行時,才會失敗並傳回 false(請參閱下方)。
由於經常誤用 exec
取代 system
,因此如果在空語境中呼叫 exec
,且後續陳述並非 die
、warn
或 exit
(如果已啟用 警告,但您總是這麼做,對吧?),Perl 會發出警告。如果您真的想要在 exec
之後加上其他陳述,可以使用下列其中一種樣式來避免警告
exec ('foo') or print STDERR "couldn't exec foo: $!";
{ exec ('foo') }; print STDERR "couldn't exec foo: $!";
如果 LIST 中有多個參數,則會呼叫 execvp(3),並使用 LIST 中的參數。如果 LIST 中只有一個元素,則會檢查參數是否有 shell 元字元,如果有,則會將整個參數傳遞給系統的命令 shell 以進行剖析(在 Unix 平台上為 /bin/sh -c
,但在其他平台上則有所不同)。如果參數中沒有 shell 元字元,則會將其拆分為字詞,並直接傳遞給 execvp
,這樣更有效率。範例
exec '/bin/echo', 'Your arguments are: ', @ARGV;
exec "sort $outfile | uniq";
如果你不想執行第一個參數,但想要對你正在執行的程式隱瞞其自己的名稱,你可以指定你實際上想要執行的程式為 LIST 前面的「間接物件」(沒有逗號),例如 exec PROGRAM LIST
。(這會強制將 LIST 解釋為多值清單,即使清單中只有一個單一純量。)範例
my $shell = '/bin/csh';
exec $shell '-sh'; # pretend it's a login shell
或更直接地說,
exec {'/bin/csh'} '-sh'; # pretend it's a login shell
當參數透過系統 shell 執行時,結果會受到其怪癖和功能的影響。請參閱 perlop 中的「`STRING`」 以取得詳細資訊。
在 exec
或 system
中使用間接物件也更安全。此用法(在 system
中也能正常運作)強制將參數解釋為多值清單,即使清單只有一個參數。這樣一來,你可以避免 shell 展開萬用字元或將其中包含空白字元的字詞拆分。
my @args = ( "echo surprise" );
exec @args; # subject to shell escapes
# if @args == 1
exec { $args[0] } @args; # safe even with one-arg list
第一個版本(沒有間接物件的那個)執行了 echo 程式,並將 "surprise"
傳遞給它作為參數。第二個版本沒有執行;它試圖執行一個名為 "echo surprise" 的程式,但找不到它,並將 $?
設定為非零值,表示失敗。
在 Windows 上,只有 exec PROGRAM LIST
間接物件語法才能可靠地避免使用 shell;exec LIST
,即使有多個元素,如果第一次產生失敗,也會退回到 shell。
Perl 會嘗試在執行前清除所有已開啟的輸出檔案,但某些平台可能不支援此功能(請參閱 perlport)。為了安全起見,你可能需要設定 $|
(英文 中的 $AUTOFLUSH
)或呼叫 IO::Handle
中任何開啟處理的 autoflush
方法,以避免遺失輸出。
請注意,exec
呼叫不會呼叫您的 END
區塊,也不會在您的物件上呼叫 DESTROY
方法。
可移植性問題:perlport 中的「exec」。