我有一个PHP脚本,它使用管道命令调用系统shell。在这种情况下,我们讨论的是备份脚本(但它可能是任何东西,我具体询问退出状态!):
exec(
"mysqldump --user=$u --password=$p --host=$h --port=$p $db | gzip -9 > backup.sql.gz",
$out,
$status
);
现在我想知道mysqldump命令是否产生了错误,但$status
变量似乎总是包含0
,即使我强制错误。它似乎是第二个命令的退出代码(在本例中为gzip)。我希望能够在PHP中看到第一个命令的退出状态。
答案 0 :(得分:3)
您需要Bash内部数组list
的一点帮助。这保存了管道中每个命令的退出状态。由于您正在寻找第一个命令的退出状态,因此您将处理PIPESTATUS
。所以你的代码看起来像是:
PIPESTATUS[0]
请注意,这会更改exec(
"bash -c 'mysqldump --user=$u --password=$p --host=$h --port=$p $db | gzip -9 > backup.sql.gz; exit \${PIPESTATUS[0]}'",
$out,
$status
);
调用的整体退出状态,如果您希望在较长的命令链中发现故障,则需要其他代码。
答案 1 :(得分:0)
我设法想到一个更通用的解决方案,使得管道中每个命令的退出状态可供PHP使用。当然它需要一个>>> list2d = ((1, 2, 3),(4, 5, 6), (7,), (8, 9))
>>> %timeit reduce(operator.concat, list2d)
1000000 loops, best of 3: 492 ns per loop
的shell(这不包括普通$PIPESTATUS
)。
sh
如果您确定管道命令将以换行符结束(请注意命令中的// The command with pipes.
$command = 'command1 | command2 | echo Test | gzip -9 -f';
// Execute the command. The overall exit code is in $exitStatus.
exec(
$command . '; echo -e "\n"${PIPESTATUS[*]}',
$out,
$exitStatus
);
// Get the exit statuses and remove them from the output.
$pipeStatus = explode(' ', array_pop($out));
print_r([$pipeStatus, $out]);
// [
// [
// "127",
// "127",
// "0",
// "0",
// ],
// [
// b"\x1F‹\x089fÙW\x02I-.á\x02Â\x1Axú\x05",
// ],
// ]
部分不同),稍微简单一点的变体:
echo