system LIST
system PROGRAM LIST

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::Handleautoflush 方法。

返回值是程序的退出状态,由 wait 调用返回。要获取实际的退出值,请右移八位(见下文)。另请参见 exec。这不是您用来捕获命令输出的内容;为此,您应该只使用反引号或 qx//,如 "`STRING`" in perlop 中所述。返回值 -1 表示无法启动程序或 wait(2) 系统调用出错(检查 $! 以了解原因)。

如果您想让 system(以及 Perl 的许多其他部分)在出错时退出,请查看 autodie 编译指示。

exec 一样,system 允许您使用 system PROGRAM LIST 语法对程序的名称撒谎。再次,请参见 exec

由于在执行 system 期间忽略了 SIGINTSIGQUIT,如果您希望程序在收到这些信号时终止,则需要根据返回值自行安排。

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 perlopexec

由于 system 执行了 forkwait,它可能会影响 SIGCHLD 处理程序。有关详细信息,请参见 perlipc

可移植性问题:"system" in perlport