exec LIST
exec PROGRAM LIST

The exec 函数执行系统命令并且永远不会返回; 如果您希望它返回,请使用 system 而不是 exec。 它只在命令不存在并且直接执行而不是通过系统的命令 shell 执行时才会失败并返回 false(见下文)。

由于使用 exec 而不是 system 是一个常见的错误,因此如果 exec 在空上下文调用,并且后面跟着一个不是 diewarnexit 的语句,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`”

使用间接对象与 execsystem 也是更安全的。这种用法(也适用于 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 尝试在 exec 之前刷新所有打开以供输出的文件,但这在某些平台上可能不受支持(请参阅 perlport)。为了安全起见,您可能需要设置 $|(在 English 中为 $AUTOFLUSH)或在任何打开的句柄上调用 IO::Handleautoflush 方法,以避免丢失输出。

请注意,exec 不会调用您的 END 块,也不会调用您对象的 DESTROY 方法。

可移植性问题:perlport 中的“exec”