如何处理shell脚本中的错误/exception?

下面是我在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 

问题陈述:-

在我上面的shell脚本中必须每天使用cron job运行,我没有任何error/exception handling mechanism 。 假设有什么不对的地方,我不知道发生了什么事情?

在执行上面的脚本之后,还有some other scripts that will be dependent on the data provided by above script ,所以我总是从其他依赖脚本数据的人那里投诉,发生了错误。

那么有什么办法可以get notified if anything wrong has happened在我的脚本中get notified if anything wrong has happenedget notified if anything wrong has happened ? 假设如果cluster is having some maintenance正在进行cluster is having some maintenance ,那么当时我正在运行我的脚本,所以肯定会失败,所以如果我的上面的脚本失败了,我可以通知,这样我就可以确定发生了什么错误。

希望我的问题很清楚。

任何想法将不胜感激。

Solutions Collecting From Web of "如何处理shell脚本中的错误/exception?"

您可以检查每个命令的退出状态,正如freetx所回答的,但这是手动错误检查而不是异常处理。 在sh获得等价的异常处理的标准方法是使用set -e来启动脚本。 这sh一旦任何执行的命令失败(即以非零退出状态退出), sh就以非零状态退出。

如果这个脚本中的一些命令可能(可能)失败,那么可以使用构造COMMAND || true 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 

另一种确保在cron调用的脚本中出现问题时得到通知的方法是坚持Unix的约定, 除非出现错误,否则不打印任何东西 。 成功的运行将在没有通知的情况下通过,不成功的运行将导致cron守护进程通过电子邮件通知您错误。 请注意,本地邮件传递必须在您的系统上正确配置才能正常工作。

对于每个unix命令行实用程序,它的习惯是在成功时返回0,在失败时返回非零。 所以你可以使用$? 模式来显示最后的返回值并相应地处理事物。

例如:

 > ls > file1 file2 > echo $? > 0 > ls file.no.exist > echo $? > 1 

因此,你可以使用这个作为基本的错误检测,看看是否有什么问题。 所以正常的做法是

 some_command if [ $? -gt 0 ] then handle_error here fi 

那么如果其他脚本在同一台机器上,那么你可以在脚本的其他脚本中做一个pgrep,如果发现睡了一会儿,并尝试其他脚本,以后再检查过程消失了。

如果脚本在另一台机器上,或者甚至是本地的,另一种方法是在远程机器上生成一个临时文件,这个文件可以通过运行的http浏览器访问,其他脚本可以检查状态,

您也可以将脚本包装到另一个查找这些错误的脚本中,如果发现它,则发送电子邮件,如果不按照常规发送结果

 go=0; function check_running() { running=`pgrep -f your_script.sh|wc -l ` if [ $running -gt 1 ]; then echo "already running $0 -- instances found $running "; go=1; } check_running; if [ $go -ge 1 ];then execute your other script else sleep 120; check_running; fi