即使发生错误,PHP exec 命令的结果也为 0

即使发生错误,PHP exec 命令的结果也为 0

我有这个 PHP 代码:

$execout=exec('ssh [email protected] "sudo /etc/init.d/smokeping reload"',$output1,$result);
if($result !=0){
    echo"that can't reload";
}
else{
    echo "successfully reloaded";
}

在此代码中,始终给出$result = 0.这是为什么?有时如果smokeping有错误,在命令行中输入以下命令时会显示该错误,

ssh [email protected] "sudo /etc/init.d/smokeping reload"

然后它给出这个错误消息。

* Reloading latency logger daemon configuration...
ERROR: can't open /etc/smokeping/devices/errorfilename: No such file or   directory
 ...done.

所以它有一个错误,但$result每次都给出与 0 相同的值。 (是否有错误)

为什么 exec 命令的行为是这样的(在 php 和 CLI 中)?

答案1

ssh [email protected] "sudo /etc/init.d/smokeping reload"

你的壳

(1) (或者在您的示例中,由 PHP 启动的 shell exec())将解析该命令行,如果找到则执行ssh

(2) 将联系的命令sshd

(3)xxx.xxx.xxx.xx认证成功后调用的服务器shell

(4) 它将解释该sudo命令行并运行sudo

(5) 检查权限后将运行的命令/etc/init.d/smokeping

(6) 它本身可能是一个运行多个命令的 shell 脚本。

有几件事可能会失败。如果所有步骤 1 到 5 均成功,则 的退出状态/etc/init.d/smokeping将报告给您的 shell,因为它sudo会报告其运行的命令的退出状态,并且远程 shell 将以其运行的最后一个命令的退出状态退出并ssh报告远程 shell 的退出状态。

现在,按照惯例,命令会返回非零退出状态,以向调用者报告他们尚未完成要求执行的操作。

在您的情况下,要么/etc/init.d/smokeping认为发生的任何错误都不足以保证非零退出状态,要么脚本编写不正确,并且在失败时无法以非零退出状态返回(或者涉及不当行为或某些病态情况)sshsudo远程 shell的配置错误)。

/etc/init.d脚本通常是用set -e.启用该标志后,解释脚本的 shell 将在运行命令失败时默认退出(失败命令的退出状态为非零),这让我认为我们可能处于第一种情况:“冒烟”确实决定报告它已成功重新加载。

病态情况的一个例子可能是:bash用作远程 shell(即使它们不是交互式 shell,在调用时bash也会读取),并且具有类似以下内容的内容:~/.bashrcssh~/.bashrc

trap 'whatever...; exit 0' EXIT

ssh这将导致交互式 shell 或 shell 重新启动或rsh始终为 的退出状态0

答案2

2>&1我找到了一个小答案。对于我放在最后的上面的代码。作为

$execout=exec('ssh [email protected] "sudo /etc/init.d/smokeping reload 2>&1"',$output1,$result);

当我要重新加载(smokeping)的应用程序中发生错误时,print_r($output);给出的错误为

Array ( [0] => * Reloading latency logger daemon configuration... [1] => ERROR: can't open /etc/smokeping/devices/errorfilename: No such file or directory [2] => ...done. )

现在我可以从这里处理了。谢谢大家。

相关内容