和 exec
做的事情完全一樣,只是會先執行 fork,然後父進程等待子進程退出。請注意,根據參數的數量,參數處理方式有所不同。如果 LIST 中有多個參數,或者 LIST 是一個包含多個值的陣列,則以列表的第一個元素為程序啟動,其餘的參數作為該程序的參數。如果只有一個標量參數,則會檢查該參數是否包含 shell 元字符,如果有,則將整個參數傳遞給系統的命令 shell 進行解析(在 Unix 平台上是 /bin/sh -c
,但在其他平台上會有所不同)。如果參數中沒有 shell 元字符,則會將其拆分成單詞並直接傳遞給 execvp
,這樣更有效率。在 Windows 上,只有使用 system PROGRAM LIST
語法才能可靠地避免使用 shell;即使有多個元素,使用 system LIST
也會在第一次嘗試失敗後回退到 shell。
在進行可能執行 fork 的任何操作之前,Perl 會嘗試刷新所有以輸出模式打開的文件,但這在某些平台上可能不受支持(請參閱 perlport)。為了確保安全,您可能需要設置 $|
(在 English 中是 $AUTOFLUSH
)或在任何打開的處理程序上調用 IO::Handle
的 autoflush
方法。
返回值是由 wait
調用返回的程序退出狀態。要獲取實際的退出值,請右移八位(見下文)。另請參閱 exec
。這 不是 用於捕獲命令輸出的正確方式;對於這個目的,您應該僅僅使用反引號或 qx//
,如 perlop 中的 "`STRING`" 中
如果您想要讓 system
(以及許多其他 Perl 部分)在出錯時終止,請查看 autodie pragma。
與 exec
類似,system
允許您在使用 system PROGRAM LIST
語法時欺騙程序關於其名稱。再次參見 exec
。
由於在執行 system
時會忽略 SIGINT
和 SIGQUIT
,如果您期望您的程序在接收到這些信號時終止,您將需要根據返回值自行安排終止。
my @args = ("command", "arg1", "arg2");
system(@args) == 0
or die "system @args failed: $?";
如果您想要手動檢查 system
的失敗,您可以像這樣檢查所有可能的失敗模式,檢查 $?
。
if ($? == -1) {
print "failed to execute: $!\n";
}
elsif ($? & 127) {
printf "child died with signal %d, %s coredump\n",
($? & 127), ($? & 128) ? 'with' : 'without';
}
else {
printf "child exited with value %d\n", $? >> 8;
}
或者,您可以使用 W*()
調用從 POSIX 模塊檢查 ${^CHILD_ERROR_NATIVE}
的值。
當 system
的參數由 shell 間接執行時,結果和返回碼會受到其怪癖的影響。詳情請參閱 perlop 中的 "`STRING`" 和 exec
。
由於 system
執行了 fork
和 wait
,它可能會影響 SIGCHLD
處理程序。詳情請參閱 perlipc。
可移植性問題: 請參閱 perlport 中的 "system"。