bash 如何处理shell脚本中的错误/异常?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12335356/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to handle error/exception in shell script?
提问by arsenal
Below is my script that I am executing in the bash. And it works fine.
下面是我在 bash 中执行的脚本。它工作正常。
fileexist=0
for i in $( ls /data/read-only/clv/daily/Finished-HADOOP_EXPORT_&processDate#.done); do
mv /data/read-only/clv/daily/Finished-HADOOP_EXPORT_&processDate#.done /data/read-only/clv/daily/archieve-wip/
fileexist=1
done
Problem Statement:-
问题陈述:-
In my above shell script which has to be run daily using cron job, I don't have any error/exception handling mechanism. Suppose if anything gets wrong then I don't know what's has happened?
在我上面必须每天使用的 shell 脚本中cron job,我没有任何error/exception handling mechanism. 假设如果出现任何问题,那么我不知道发生了什么?
As after the above script is executed, there are some other scripts that will be dependent on the data provided by above script, so I always get's complaint from the other people who are depending on my script data that something wrong has happened.
由于在执行上述脚本后,有some other scripts that will be dependent on the data provided by above script,所以我总是从其他依赖我的脚本数据的人那里抱怨发生了错误。
So is there any way I can get notified if anything wrong has happenedin my script? Suppose if the cluster is having some maintenanceand at that time I am running my script, so definitely it will be failing for sure, so can I be notified if my above scripts failed, so that I will be sure something wrong has happened.
那么有什么办法可以get notified if anything wrong has happened在我的脚本中使用吗?假设cluster is having some maintenance当时我正在运行我的脚本,那么它肯定会失败,所以如果我的上述脚本失败,我可以得到通知,这样我就可以确定发生了错误。
Hope my question is clear enough.
希望我的问题足够清楚。
Any thoughts will be appreciated.
任何想法将不胜感激。
回答by user4815162342
You can check for the exit status of each command, as freetx answered, but this is manual error checking rather than exception handling. The standard way to get the equivalent of exception handling in shis to start the script with set -e. That tells shto exit with a non-zero status as soon as any executed command fails (i.e. exits with a non-zero exit status).
您可以检查每个命令的退出状态,正如 freetx 所回答的那样,但这是手动错误检查而不是异常处理。获得等价于异常处理的标准方法sh是用set -e. sh一旦任何执行的命令失败(即以非零退出状态退出),它就会告诉以非零状态退出。
If it is intended for some command in such a script to (possibly) fail, you can use the construct COMMAND || true, which will force a zero exit status for that expression. For example:
如果打算让此类脚本中的某些命令(可能)失败,则可以使用构造COMMAND || true,这将强制该表达式的退出状态为零。例如:
#!/bin/sh
# if any of the following fails, the script fails
set -e
mkdir -p destdir/1/2
mv foo destdir/1/2
touch /done || true # allowed to fail
Another way to ensure that you are notified when things go wrong in a script invoked by cron is to adhere to the Unix convention of printing nothing unless an error ocurred. Successful runs will then pass without notice, and unsuccessful runs will cause the cron daemon to notify you of the error via email. Note that local mail delivery must be correctly configured on your system for this to work.
确保在 cron 调用的脚本出现问题时通知您的另一种方法是遵守 Unix 约定,除非发生错误,否则不打印任何内容。成功的运行将在没有通知的情况下通过,不成功的运行将导致 cron 守护程序通过电子邮件通知您错误。请注意,必须在您的系统上正确配置本地邮件传递才能使其正常工作。
回答by freetx
Its customary for every unix command line utility to return 0 upon success and non-zero on failure. Therefore you can use the $? pattern to display the last return value and handle things accordingly.
对于每个 unix 命令行实用程序,成功时返回 0,失败时返回非零。因此,您可以使用 $? 模式来显示最后的返回值并相应地处理事情。
For instance:
例如:
> ls
> file1 file2
> echo $?
> 0
> ls file.no.exist
> echo $?
> 1
Therefore, you can use this as rudimentary error detection to see if something goes wrong. So the normal approach would be
因此,您可以将其用作基本错误检测,以查看是否出现问题。所以正常的方法是
some_command
if [ $? -gt 0 ]
then
handle_error here
fi
回答by V H
well if other scripts are on the same machine, then you could do a pgrep in other scripts for this script if found to sleep for a while and try other scripts later rechecking process is gone.
好吧,如果其他脚本在同一台机器上,那么您可以在其他脚本中为该脚本执行 pgrep,如果发现睡眠一段时间并稍后尝试其他脚本重新检查过程消失了。
If script is on another machine or even local the other method is to produce a temp file on remote machine accessible via a running http browser that other scripts can check status i.e. running or complete
如果脚本在另一台机器上或什至是本地的,另一种方法是在远程机器上生成一个临时文件,该文件可通过正在运行的 http 浏览器访问,其他脚本可以检查状态,即正在运行或完成
You could also either wrap script around another that looks for these errors and emails you if it finds it if not sends result as per normal to who ever
您也可以将脚本包装在另一个查找这些错误的脚本中,如果找到,则向您发送电子邮件,如果没有按照正常方式将结果发送给任何人
go=0;
function check_running() {
running=`pgrep -f your_script.sh|wc -l `
if [ $running -gt 1 ]; then
echo "already running ##代码## -- instances found $running ";
go=1;
}
check_running;
if [ $go -ge 1 ];then
execute your other script
else
sleep 120;
check_running;
fi

