今天,我发现我的shell脚本偶尔会提前退出。在检查代码之后,我发现这是因为我在shell脚本的头部有一个set -e
,我使用内置函数RANDOM
生成一个随机数。
使用set -e
,如果脚本中的任何命令返回非零,脚本将立即退出。所以我写了一段像这样的测试代码:
set -u
#set -e
for (( i=0; i < 100; i++ ))
do
index=$(expr ${RANDOM} % 16)
echo "RANDOM return $? , index is $index"
done
注意评论set -e
,我这样做是为了显示100输出行,其中一些RANDOM return 1
确实存在。例如,我得到这样的结果:
RANDOM return 0 , index is 2
RANDOM return 0 , index is 10
RANDOM return 1 , index is 0
RANDOM return 0 , index is 9
RANDOM return 0 , index is 5
RANDOM return 0 , index is 9
RANDOM return 0 , index is 4
RANDOM return 0 , index is 6
RANDOM return 0 , index is 2
RANDOM return 0 , index is 4
RANDOM return 0 , index is 14
RANDOM return 0 , index is 6
RANDOM return 0 , index is 2
RANDOM return 1 , index is 0
RANDOM return 0 , index is 1
RANDOM return 0 , index is 8
...(more line)
请参阅? RANDOM返回1,但它正确生成随机数,这就是我的shell脚本提前退出的原因。切换到python的随机数生成代码后,我的脚本恢复正常。
为什么RANDOM
会返回1?
答案 0 :(得分:7)
$?
是您执行的最后一个命令的状态。 $RANDOM
不是命令,因此评估它不会影响$?
。 ($RANDOM
是一个“shell参数”或变量,在计算它时会产生0到32767之间的随机整数。)
您看到的$?
值是执行命令expr ${RANDOM} % 16
的结果。
如果评估表达式的结果为空或expr
,1
命令将返回状态0
,因此每当1
时,您将获得$RANDOM % 16
状态{1}}为0(6.25%的时间)。
% expr 1 % 16 ; echo "\$?=$?"
1
$?=0
% expr 0 % 16 ; echo "\$?=$?"
0
$?=1
如果您已完成set -e
并且想要在不终止shell的情况下执行可能失败的命令,则可以附加|| true
之类的内容。由于||
的前缀用作条件,因此失败只会使条件为假。
index=$(expr ${RANDOM} % 16) || true
echo "Status of expr is $?, index is $index"