与 exec
的功能完全相同,只是它首先进行 fork 操作,然后父进程等待子进程退出。请注意,参数处理方式会根据参数数量而有所不同。如果 LIST 中有多个参数,或者 LIST 是一个包含多个值的数组,则使用列表中的第一个元素作为程序名称,其余元素作为参数启动该程序。如果只有一个标量参数,则会检查该参数是否包含 shell 元字符,如果有,则将整个参数传递给系统的命令 shell 进行解析(在 Unix 平台上是 /bin/sh -c
,但在其他平台上有所不同)。如果参数中没有 shell 元字符,则将其拆分为单词并直接传递给 execvp
,这更有效率。在 Windows 上,只有 system PROGRAM LIST
语法才能可靠地避免使用 shell;即使 system LIST
中有多个元素,如果第一个 spawn 失败,也会回退到 shell。
Perl 会尝试在任何可能进行 fork 的操作之前刷新所有打开的输出文件,但这在某些平台上可能不受支持(参见 perlport)。为了安全起见,您可能需要设置 $|
(在 English 中为 $AUTOFLUSH
)或在任何打开的句柄上调用 IO::Handle
的 autoflush
方法。
返回值是程序的退出状态,由 wait
调用返回。要获取实际的退出值,请右移八位(见下文)。另请参见 exec
。这不是您用来捕获命令输出的内容;为此,您应该只使用反引号或 qx//
,如 "`STRING`" in perlop 中所述。返回值 -1 表示无法启动程序或 wait(2) 系统调用出错(检查 $!
以了解原因)。
如果您想让 system
(以及 Perl 的许多其他部分)在出错时退出,请查看 autodie 编译指示。
与 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;
}
或者,您可以使用 POSIX 模块中的 W*()
调用检查 ${^CHILD_ERROR_NATIVE}
的值。
当 system
的参数由 shell 间接执行时,结果和返回值会受到其怪癖的影响。有关详细信息,请参见 "`STRING`" in perlop 和 exec
。
由于 system
执行了 fork
和 wait
,它可能会影响 SIGCHLD
处理程序。有关详细信息,请参见 perlipc。
可移植性问题:"system" in perlport。