![当 PIPED 命令遇到错误时如何停止 bash 脚本?](https://linux22.com/image/1191675/%E5%BD%93%20PIPED%20%E5%91%BD%E4%BB%A4%E9%81%87%E5%88%B0%E9%94%99%E8%AF%AF%E6%97%B6%E5%A6%82%E4%BD%95%E5%81%9C%E6%AD%A2%20bash%20%E8%84%9A%E6%9C%AC%EF%BC%9F.png)
我的 bash 脚本中有一些管道,特别是mysqldump | mysql
如果任何的管道进程返回非零退出代码?
在我的测试中,如果失败,尽管脚本开始时mysqldump
有语句,脚本仍会继续。set -e
答案1
您可能想要设置 shell 的pipefail
选项:
pipefail If set, the return value of a pipeline is the value of the last (rightmost) command to exit with a non-zero status, or zero if all commands in the pipeline exit successfully. This option is disabled by default.
因此,set -eo pipefail
代替只是set -e
。另请参阅使用管道时检索状态代码。
答案2
您需要检查 shell 提供的 $? 变量的值。如果您在没有管道的情况下运行失败的命令,它将给出错误代码 1;如果您在管道之后检查它,它可能会给出错误代码 127。如果它不为零,则操作失败。(简而言之。)
不带错误检查的管道并不是一个好的解决方案。将其写入检查 $? 变量值的小型 shell 脚本中:
#!/bin/bash
# run first command here...
mysqldump > output.dump
if [ "$?" = 0 ] ; then
# do the second thing here
cat output.dump | mysql
fi
if [ "$?" = 0 ] ; then
# this is checking now that the mysql program didn't throw an error
echo "Operation Successful!"
else
echo "Operation failed!"
fi
我们仍在这里使用管道,但在使用数据之前验证转储是否成功。
仅仅检查“输出”是否存在是无效的,因为根据命运,一旦开始转储过程,它可能会也可能不会创建文件名。您应该假设任何命令都会失败。管道机制主要用于一次性命令,实际上没有任何错误检测。如果您多次执行此过程,那么您应该有一个检查错误代码的脚本。