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

Eri*_*eng 0 bash shell

今天,我发现我的shell脚本偶尔会提前退出.检查代码后,我发现这是因为set -e我的shell脚本中有一个,我使用内置函数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
Run Code Online (Sandbox Code Playgroud)

注意评论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)
Run Code Online (Sandbox Code Playgroud)

看到?RANDOM返回1,但它正确生成随机数,这就是我的shell脚本提前退出的原因.切换到python的随机数生成代码后,我的脚本恢复正常.

为什么会RANDOM返回1?

Kei*_*son 7

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

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

expr命令返回的状态是,1如果计算表达式的结果为null 0,那么您将获得1每当$RANDOM % 16为0(6.25%的时间)时的状态.

% expr 1 % 16 ; echo "\$?=$?"
1
$?=0
% expr 0 % 16 ; echo "\$?=$?"
0
$?=1
Run Code Online (Sandbox Code Playgroud)

如果你已经完成set -e并且想要执行一个可能在不终止shell的情况下失败的命令,你可以添加类似的东西|| true.由于前缀to ||用作条件,因此失败只会使条件为假.

index=$(expr ${RANDOM} % 16) || true
echo "Status of expr is $?, index is $index"
Run Code Online (Sandbox Code Playgroud)