Shell - 为什么内置的RANDOM函数返回1?

时间:2016-09-29 03:45:32

标签: bash shell

今天,我发现我的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?

1 个答案:

答案 0 :(得分:7)

$?是您执行的最后一个命令的状态。 $RANDOM不是命令,因此评估它不会影响$?。 ($RANDOM是一个“shell参数”或变量,在计算它时会产生0到32767之间的随机整数。)

您看到的$?值是执行命令expr ${RANDOM} % 16的结果。

如果评估表达式的结果为空或expr1命令将返回状态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"