Bash 怪异:与条件相关的算术表达式的退出代码。 true/false 对比 success/failure
Bash Weirdness: Exit Codes of Arithmetic Expressions in Relation to Conditionals. true/false vs. success/failure
根据 bash
man
页面,
while list-1; do list-2; done
The while command continuously executes the list list-2 as long as the last command in the list, list-1, returns an exit status of zero.
我试图弄清楚 bash 如何解释出现在列表 1 末尾的算术表达式的退出代码。我开始了一些实验:
$ echo $((1))
1
$ ((1)); echo $?
0
$ echo $((! 1))
0
$ ((! 1)); echo $? # Hm, what does this exit code mean?
1
$ while ((1)); do echo "yes"; break; done
yes
# This could be responding to either the exit code of ((1))
# or to it's value, 1 meaning true
$ while ((! 1)); do echo "yes"; break; done
# This could be responding to either the exit code of ((! 1)),
# or to it's value, 0 meaning false
$ while ! ((1)); do echo "yes"; break; done
# this ! should change the exit code, not the value,
# so it appear to be responding to the exit code
$ echo $((0))
0
$ ((0)); echo $? # Hm, what does this exit code mean?
1
$ echo $((! 0)))
1
$ ((! 0)); echo $?
0
$ while ((0)); do echo "yes"; break; done
# This could be responding to either the exit code of ((0))
# or to it's value, 0 meaning false
$ while ((! 0)); do echo "yes"; break; done
yes
# This could be responding to either the exit code of ((! 0))
# or to it's value, 1 meaning true
$ while ! ((0)); do echo "yes"; break; done
yes
# this ! should change the exit code, not the value,
# so it appears to be responding to the exit code.
因此,在修复两个错误后(感谢@Barmar),有一个基于 while 循环查看退出代码的一致解释。仍然不清楚的是为什么 ((0))
的退出代码是失败,而 ((1))
的退出代码是成功。
我在尝试捕获 while 条件下函数的退出代码以供循环中断时使用时遇到了这个问题:
while <function>; do
<stuff>
done
# I need the exit code of <function> here.
所以,也许这样:
while <function>; ((! (RESULT=$?) )); do # alternative ! (( RESULT=$? ))
<stuff>
done
bash
所做的是将计算结果为 1
的 ((1))
与“真相”相关联。然后它通过 return 成功退出代码 0
使其与退出代码一致。同样,它将计算结果为 0
的 ((0))
关联到“false”。它们通过 return 失败的退出代码 1
.
使其与退出代码一致
这可能看起来令人困惑,因为毕竟两个评估 ((.))
都是“成功的”,但这是使表示 true/false 的算术表达式的值与 [=26= 一致的 hack ] 的 success/failure 退出代码,并使 if ...; then ...; fi
、while ...; do ...; done
等条件表达式正常工作。
任何计算结果为零的都是假的,任何不是零的都是真的。
这意味着您可以执行以下操作:
while :; do
((c++%5)) || ((val=RANDOM))
echo "$val changes every 5 iterations"
sleep 0.5
done
负数不为零:
$ ((20-30)); echo $?
0
$ ((20-20)); echo $?
1
$ ((20-10)); echo $?
0
对于((! 0))
,0的逻辑非为1,((1))
return为真(0)。对于 !((0))
,return 值 false (1) 被(非算术)运算符 !
否定,导致算术子 shell 的 return 值为真( 0) 而不是假的。
根据 bash
man
页面,
while list-1; do list-2; done
The while command continuously executes the list list-2 as long as the last command in the list, list-1, returns an exit status of zero.
我试图弄清楚 bash 如何解释出现在列表 1 末尾的算术表达式的退出代码。我开始了一些实验:
$ echo $((1))
1
$ ((1)); echo $?
0
$ echo $((! 1))
0
$ ((! 1)); echo $? # Hm, what does this exit code mean?
1
$ while ((1)); do echo "yes"; break; done
yes
# This could be responding to either the exit code of ((1))
# or to it's value, 1 meaning true
$ while ((! 1)); do echo "yes"; break; done
# This could be responding to either the exit code of ((! 1)),
# or to it's value, 0 meaning false
$ while ! ((1)); do echo "yes"; break; done
# this ! should change the exit code, not the value,
# so it appear to be responding to the exit code
$ echo $((0))
0
$ ((0)); echo $? # Hm, what does this exit code mean?
1
$ echo $((! 0)))
1
$ ((! 0)); echo $?
0
$ while ((0)); do echo "yes"; break; done
# This could be responding to either the exit code of ((0))
# or to it's value, 0 meaning false
$ while ((! 0)); do echo "yes"; break; done
yes
# This could be responding to either the exit code of ((! 0))
# or to it's value, 1 meaning true
$ while ! ((0)); do echo "yes"; break; done
yes
# this ! should change the exit code, not the value,
# so it appears to be responding to the exit code.
因此,在修复两个错误后(感谢@Barmar),有一个基于 while 循环查看退出代码的一致解释。仍然不清楚的是为什么 ((0))
的退出代码是失败,而 ((1))
的退出代码是成功。
我在尝试捕获 while 条件下函数的退出代码以供循环中断时使用时遇到了这个问题:
while <function>; do
<stuff>
done
# I need the exit code of <function> here.
所以,也许这样:
while <function>; ((! (RESULT=$?) )); do # alternative ! (( RESULT=$? ))
<stuff>
done
bash
所做的是将计算结果为 1
的 ((1))
与“真相”相关联。然后它通过 return 成功退出代码 0
使其与退出代码一致。同样,它将计算结果为 0
的 ((0))
关联到“false”。它们通过 return 失败的退出代码 1
.
这可能看起来令人困惑,因为毕竟两个评估 ((.))
都是“成功的”,但这是使表示 true/false 的算术表达式的值与 [=26= 一致的 hack ] 的 success/failure 退出代码,并使 if ...; then ...; fi
、while ...; do ...; done
等条件表达式正常工作。
任何计算结果为零的都是假的,任何不是零的都是真的。
这意味着您可以执行以下操作:
while :; do
((c++%5)) || ((val=RANDOM))
echo "$val changes every 5 iterations"
sleep 0.5
done
负数不为零:
$ ((20-30)); echo $?
0
$ ((20-20)); echo $?
1
$ ((20-10)); echo $?
0
对于((! 0))
,0的逻辑非为1,((1))
return为真(0)。对于 !((0))
,return 值 false (1) 被(非算术)运算符 !
否定,导致算术子 shell 的 return 值为真( 0) 而不是假的。