检测 bash 脚本中的程序错误?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1854631/
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
Detecting program errors in bash scripts?
提问by meder omuraliev
I'm trying to write my first semi advanced bash script that will take input in the form of a filename referring to an avivideo, send it to ffmpegto convert to a mp4(preserving the original name) and then hand it off to MP4Box.
我正在尝试编写我的第一个半高级 bash 脚本,该脚本将以引用avi视频的文件名的形式输入,将其发送ffmpeg到转换为mp4(保留原始名称),然后将其传递给MP4Box.
The below is pretty much what I'm doing...
下面几乎是我在做什么......
#!/usr/bin/bash
ffmpeg -i first-cmd && second-cmd
-acodec libfaac -ab 128k -ac 2 -vcodec libx264 -vpre hq -crf 22 -threads 0 (bad-cmd || echo "failed"
).mp4
MP4Box -inter 500 (good-cmd && echo "succeeded" || echo "failed"
bad-cmd || {
recovery-cmd ||
echo "recovery failed &&
echo "recovered"
}
).mp4
- Is there some sort of try/catch I can do for the first program invocation to make sure MP4Box gets workable input?
- Should I even bother with error catching at all, should I instead rely on the programs themselves to do this for me?
- 我可以为第一次程序调用做某种尝试/捕获以确保 MP4Box 获得可用的输入吗?
- 我什至应该为捕获错误而烦恼,我应该依靠程序本身来为我做这件事吗?
回答by Paused until further notice.
One quick way to make the execution of one program dependent on the success of another is to use &&. (the commands below are all pseudo-code)
使一个程序的执行依赖于另一个程序的成功的一种快速方法是使用&&. (以下命令均为伪代码)
bad-cmd 2>/dev/null # send error message to the bit bucket
var=$(good-cmd) # capture stdout
var=$(bad-cmd 2>&1) # capture stdout and stderr
var=$(bad-cmd 2>&1 >/dev/null) # capture only stderr
In this case second-cmd will only be executed if first-cmd returns true.
在这种情况下,只有在 first-cmd 返回 true 时才会执行 second-cmd。
Likewise, you can test for failure and take appropriate action using ||
同样,您可以测试失败并使用适当的操作 ||
ffmpeg <your args>
RC=$?
if [ "${RC}" -ne "0" ]; then
# Do something to handle the error.
else
# Everything was ok.
fi
You can combine them in various ways:
您可以通过多种方式组合它们:
lskdf # Unrecognized command.
echo $? # Non-zero exit status returned because command failed to execute.
Of course, it's often clearer to use the special variable $?that others have noted.
当然,使用$?其他人已经注意到的特殊变量通常会更清晰。
You will often want to redirect error messages to /dev/nullor capture them in a variable.
您通常希望将错误消息重定向到/dev/null变量或将它们捕获到变量中。
Then you can process the text of the error to obtain additional information for conditional action in your code.
然后,您可以处理错误文本以获取代码中条件操作的附加信息。
See: Capture output in a variableand How can I redirect stderr to a pipe?
回答by Tom Duckering
On the whole you can check the return code to determine the result of a command. You can get the return code of the previously executed command using the special variable $?. Beware that it's update after every command so use it to set another variable. For example RC = $?. Return codes are normally 0 for success and non-zero for failures. Specific non zero return codes may indicate particular types of failure. Check the man page of your command to find out exactly how to interpret them. Once you have the return code you can use it to branch. For example:
总的来说,您可以通过检查返回码来确定命令的结果。您可以使用特殊变量获取先前执行的命令的返回码$?。请注意,它会在每个命令之后更新,因此请使用它来设置另一个变量。例如RC = $?。返回码通常为 0 表示成功,非零表示失败。特定的非零返回码可能表示特定类型的故障。检查您的命令的手册页以准确了解如何解释它们。获得返回码后,您可以使用它进行分支。例如:
回答by RnR
Yes - you should worry about the errors and it's really not a big problem to do it - all you need to do is check the exit code of the application you executed - as a rule if everything went well the application should return an exit code equal to zero - take a look here if you need more details too: http://tldp.org/LDP/abs/html/exit-status.html
是的 - 你应该担心这些错误,这样做真的不是什么大问题 - 你需要做的就是检查你执行的应用程序的退出代码 - 作为一项规则,如果一切顺利,应用程序应该返回一个等于归零 - 如果您还需要更多详细信息,请查看此处:http: //tldp.org/LDP/abs/html/exit-status.html
##代码##回答by camh
You can run the shell with -e, or put the command set -ein your script. This will cause the script to terminate if any of the commands returns non-zero exit status.
您可以使用 运行 shell -e,或将命令set -e放入脚本中。如果任何命令返回非零退出状态,这将导致脚本终止。
If you need to run a command where you dont want a non-zero exit to cause the script to terminate, append || trueto the command.
如果您需要在不希望非零退出导致脚本终止|| true的情况下运行命令,请附加到该命令。
回答by diciu
If ffmpegis a good citizen, it will return an exit code of 0 on success and some other value on failure.
如果ffmpeg是一个好公民,它会在成功时返回退出代码 0,在失败时返回一些其他值。
"$?" is a special bash construct that tells the return code of the last executed process. After the ffmpeg line you can check "$?" against non-zero values and exit in error.
“$?” 是一个特殊的 bash 结构,它告诉最后执行的进程的返回码。在 ffmpeg 行之后,您可以检查“$?” 针对非零值并错误退出。

