PHP shell_exec()与exec()的比较

PHP shell_exec()与exec()的比较,php,shell,command,exec,Php,Shell,Command,Exec,我正在努力理解shell\u exec()和exec()之间的区别 我一直使用exec()来执行服务器端命令,何时使用shell\u exec() shell\u exec()只是exec()的简写吗?参数更少似乎也是一样。shell\u exec以字符串形式返回所有输出流exec返回输出的最后一行,但可以将所有输出作为指定为第二个参数的数组提供 看 -通过shell执行命令,并以字符串形式返回完整的输出 -执行外部程序 区别在于使用shell\u exec可以将输出作为返回值。以下是区别

我正在努力理解
shell\u exec()
exec()
之间的区别

我一直使用
exec()
来执行服务器端命令,何时使用
shell\u exec()


shell\u exec()
只是
exec()
的简写吗?参数更少似乎也是一样。

shell\u exec
以字符串形式返回所有输出流<默认情况下,code>exec返回输出的最后一行,但可以将所有输出作为指定为第二个参数的数组提供

-通过shell执行命令,并以字符串形式返回完整的输出

-执行外部程序


区别在于使用
shell\u exec
可以将输出作为返回值。

以下是区别。注意末尾的换行符

> shell_exec('date')
string(29) "Wed Mar  6 14:18:08 PST 2013\n"
> exec('date')
string(28) "Wed Mar  6 14:18:12 PST 2013"

> shell_exec('whoami')
string(9) "mark\n"
> exec('whoami')
string(8) "mark"

> shell_exec('ifconfig')
string(1244) "eth0      Link encap:Ethernet  HWaddr 10:bf:44:44:22:33  \n          inet addr:192.168.0.90  Bcast:192.168.0.255  Mask:255.255.255.0\n          inet6 addr: fe80::12bf:ffff:eeee:2222/64 Scope:Link\n          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1\n          RX packets:16264200 errors:0 dropped:1 overruns:0 frame:0\n          TX packets:7205647 errors:0 dropped:0 overruns:0 carrier:0\n          collisions:0 txqueuelen:1000 \n          RX bytes:13151177627 (13.1 GB)  TX bytes:2779457335 (2.7 GB)\n"...
> exec('ifconfig')
string(0) ""
请注意,的使用与相同


更新:我真的应该解释最后一个。几年后看到这个答案,我都不知道为什么答案是空的!Daniel在上面解释了这一点——这是因为
exec
只返回最后一行,而
ifconfig
的最后一行恰好是空的。

这里没有提到的几个区别:

  • 使用exec(),可以传递一个可选的param变量,该变量将接收一个输出行数组。在某些情况下,这可能会节省时间,特别是如果命令的输出已经是表格形式的话
比较:

exec('ls', $out);
var_dump($out);
// Look an array

$out = shell_exec('ls');
var_dump($out);
// Look -- a string with newlines in it
相反,如果命令的输出是xml或json,那么将每一行作为数组的一部分并不是您想要的,因为您需要将输入后处理为其他形式,因此在这种情况下,请使用shell_exec

还值得指出的是,shell_exec是backtic操作符的别名,用于*nix

$out = `ls`;
var_dump($out);
exec还支持一个附加参数,该参数将提供已执行命令的返回代码:

exec('ls', $out, $status);
if (0 === $status) {
    var_dump($out);
} else {
    echo "Command failed with status: $status";
}

如shell_exec手册页面所述,当您实际需要执行的命令返回代码时,您别无选择,只能使用exec。

如果命令出现一个错误,会发生什么情况。。?我得到了一个错误/没有这样的文件或目录,但是我怎样才能将它捕获到一个变量??@AlwinAugustin:Huh?可能正在写入STDERR。如果您在linux机器上,请尝试在命令末尾添加
2>&1
,以将STDERR重定向到STDOUT。我也添加了它。但我仍然得到0作为值。我使用了一个wc-l命令,如果文件不在那里,我需要得到错误消息说没有这样的文件或目录。如果你需要退出值和所有输出,你可能还是使用“exec”而不是“shell_exec”更好。只要你把输出参数传递给“exec”,它就会被输出的每一行所填充,在我看来,“exec”可以处理“shell_exec”等的所有内容:)@daniel-a-white我知道这是一个旧的,但是它很流行,所以你应该编辑你的答案来反映@preexo的评论——如果你使用它的可选参数,它还可以返回整个输出。另外,不相关的是,应该有人对这两个命令进行基准测试,看看哪一个更好,因为@preexo说“在我看来,
exec()
似乎可以[做]任何事情
shell\u exec()
[can,]和更多:)”此外:
exec
允许您获取命令的返回代码(通过
和$return\u var
参数),虽然
shell\u exec
没有提供获得它的方法。虽然公认的答案也是正确的,但在我看来,这个答案更重要。最好的答案可能是两者的结合。了解两者区别的好例子是尝试以下命令:
date
whoami
ifconfig
netstat
。还有其他函数:system(),passthru()…请参见,尤其是。可能重复漂亮简洁的摘要!仍应注意,
exec
返回输出的最后一行。如果需要,您可以选择传入一个数组作为第二个参数来捕获完整的输出,传入一个整数作为第三个参数来捕获shell命令的返回值,该返回值可用于错误检查。
shell_exec
的最大缺点是,如果命令失败或不产生任何输出,它将返回null,因此其返回值不能可靠地用于错误检查。