【问题标题】:PHP shell_exec() vs exec()PHP shell_exec() 与 exec()
【发布时间】:2011-10-28 23:04:54
【问题描述】:

我很难理解shell_exec()exec() 之间的区别...

我一直使用exec() 执行服务器端命令,我什么时候使用shell_exec()

shell_exec() 只是exec() 的简写吗?参数少了好像也一样。

【问题讨论】:

标签: php shell command exec


【解决方案1】:

shell_exec 将所有输出流作为字符串返回。 exec 默认返回输出的最后一行,但可以将所有输出作为指定为第二个参数的数组提供。

【讨论】:

  • 如果您需要退出值和所有输出,您可能还是使用“exec”而不是“shell_exec”更好。一旦你将输出参数传递给“exec”,它就会被输出的每一行填充,在我看来“exec”可以是“shell_exec”的所有内容等等:)
  • @daniel-a-white 我知道这是一个旧的,但它很受欢迎,所以你应该编辑你的答案以反映@preexo 的评论 - exec() 也有能力返回如果您使用其可选参数,则整个输出。此外,不相关的,有人应该对这两个命令进行基准测试,看看哪个更好,因为@preexo 说“在我看来exec() 可以 [do] 一切shell_exec() [can,] 和更多:)"
【解决方案2】:

这里有区别。注意末尾的换行符。

> 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) ""

注意backtick operator 的使用与shell_exec() 相同。

更新:我真的应该解释最后一个。多年后看着这个答案,即使我不知道为什么会出现空白! Daniel 上面解释过——这是因为exec 只返回最后一行,而ifconfig 的最后一行恰好是空白。

【讨论】:

  • 如果命令出现一个错误会发生什么..?我收到错误/没有这样的文件或目录,但是如何将其捕获到变量中????
  • @AlwinAugustin:嗯?可能正在写入 STDERR。如果您使用的是 linux 机器,请尝试在命令末尾添加 2>&1 以将 STDERR 重定向到 STDOUT。
  • 我也加了。但我仍然得到 0 作为价值。我已经使用了一个 wc -l 命令,如果文件不存在,我需要得到错误消息说没有这样的文件或目录。
【解决方案3】:

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

exec - 执行外部程序。

不同之处在于 shell_exec 您将输出作为返回值。

【讨论】:

  • 好简洁的总结!仍应注意exec 返回输出的最后一行。如果需要,您可以选择传入一个数组作为第二个参数来捕获完整的输出,并传入一个整数作为第三个参数来捕获 shell 命令的返回值,该值可用于错误检查。 shell_exec 的最大缺点是,如果命令失败或不产生任何输出,它会返回 null,因此它的返回值不能可靠地用于错误检查。
【解决方案4】:

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

  • 使用 exec(),您可以传递一个可选参数变量,该变量将接收一组输出行。在某些情况下,这可能会节省时间,尤其是在命令的输出已经是表格的情况下。

比较:

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。

【讨论】:

  • 另外:exec 可以让你获得命令的返回码(通过&$return_var 参数),而shell_exec 提供没有办​​法获得它。
  • 虽然接受的答案也是正确的,但在我看来这个答案更重要。最好的答案可能是两者的结合。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-09
  • 1970-01-01
  • 1970-01-01
  • 2011-06-23
  • 2014-09-19
  • 2013-03-24
相关资源
最近更新 更多