try/catch 的 Bash 模拟未按预期工作
Posted
技术标签:
【中文标题】try/catch 的 Bash 模拟未按预期工作【英文标题】:Bash emulation of try/catch not working as expected 【发布时间】:2015-06-02 11:11:57 【问题描述】:以下 switch 语句有奇怪的行为:
3)
if [ $state -ne $last_state ]
then
echo "state: $state"
fi
stty -F $SERIAL $BAUD -echo igncr
echo "befor cat"
cat -v $SERIAL >> $USBDRIVE/gpsData_$filecounter.txt && echo "after cat"
||
echo "catch"
state=0
last_state=3
((filecounter++))
;;
我想,当 cat 命令在执行过程中失败时,将写入“cat 之后”,而不是 || 之后的部分。将被执行。但是当我查看输出时,似乎在回显“after cat”之后发生了中断,因此实际状态不会改变,并且会再输入一次。然后 stty 也失败了(因为缺少串行适配器)。之后,cat命令再次失败,但现在进入“catch”块......
这是相关的输出:
pi@rpi ~/serial_logger $ ./serial_logger.sh
serial adapter found: ttyUSB0
state: 1
USB-Storage found: usb0
state: 3
before cat
after cat #here should be entered state 0
state: 3
stty: /dev/ttyUSB0: No such file or directory
before cat
cat: /dev/ttyUSB0: No such file or directory
catch
state: 0
USB-Storage found: usb0
state: 2
我做错了什么?
【问题讨论】:
按照你目前的逻辑,如果after cat
被回显,则说明cat
退出成功。
但是当我评论 '&& echo "after cat"' 时,行为保持不变
只要cat
成功(它似乎正在这样做),删除echo
不会有太大变化(我希望它也会成功)。
好的。当 cat 命令在串行适配器连接时启动时,它已成功。当我在 cat 已经启动并运行时断开适配器时,它是否也成功了?
【参考方案1】:
为什么它不起作用
在您的示例中,cat
成功,这就是打印“after cat”而未输入“catch group”的原因。
我想,当 cat 命令在执行过程中失败时,会写“after cat”
这个假设是错误的,只有在cat
成功时才会写入“cat 之后”,因为您使用了&&
运算符。
比||之后的部分将被执行。
请注意,没有“groupfail”之类的东西可以让您使用命令组 ( [...]
) 在 Bash 中实际模拟 try/catch 行为。考虑这个在你的组中有多行的例子:
cmd1
cmd2
|| # catch block
只要cmd2
成功,你的程序就不会进入catch块,即使cmd1
失败。
如何模拟 try/catch
但是,您可以使用 &&
运算符来模拟 try/catch 行为:
cmd1 && cmd2 && cmd3 || # catch block
这也可以写成
cmd1 && cmd2 && cmd3 ; || # catch block
你看,不管你怎么做,语法有点笨拙。
也许这个related *** question 也可以帮助你。
其他错误处理机制
最后但同样重要的是,应该提到两种常见的 Bash 错误处理机制:
为ERR
信号注册信号处理程序会导致 Bash 在命令返回非零退出状态时调用函数:
trap error_handler ERR
function error_handler()
echo error
设置errexit
shell 选项会导致您的程序在命令返回非零退出状态时立即终止(信号处理程序仍在执行):
set -e
【讨论】:
好的。但是当我使用 ' cmd1 && cmd2 && cmd3 ; || #catch block',catch块也只有cmd1才会执行,只有cmd1失败。我说的对吗? @Rush:不,只要其中一个命令失败,就会进入 catch 块。其余命令将不会执行。如果所有命令都成功,则不会进入 catch 块。 是的,我明白了。但是 catch-block 不会立即执行。仅当 cat 命令已正确启动时才会发生这种情况。这意味着串行适配器已插入。如果我在未插入串行适配器的情况下运行 cat 命令,则立即执行 catch-block @Rush:我不确定我是否理解 :-) 如果您的cat
成功,那么将不输入 catch 块。如果您的cat
失败,将立即输入。
好吧,也许我首先尝试解释一下我对成功和不成功执行的定义:命令的退出代码告诉我命令是否成功。 0 表示成功,1 表示不成功。该代码是命令的退出代码,在本例中为 cat 命令。当我们谈论退出代码时,我们也在谈论具有 endet 的命令,对吗?这意味着我无法获得退出代码,而 cat 命令仍在我的文件中从串行转换器写入内容。但是:当我断开串行转换器时,cat 命令应该给我一些退出代码!= 0以上是关于try/catch 的 Bash 模拟未按预期工作的主要内容,如果未能解决你的问题,请参考以下文章