2016-09-29 73 views
0

今天,我发现我的shell脚本偶尔会提前退出。检查代码后,我发现这是因为我的shell脚本中有一个set -e,我使用内置函数RANDOM来生成一个随机数。Shell - 为什么内置的RANDOM函数返回1?

随着set -e,如果脚本中的任何命令返回非零,脚本将立即退出。所以我写的测试代码这样的片段:在评论set -e

set -u 
#set -e 

for ((i=0; i < 100; i++)) 
do 
index=$(expr ${RANDOM} % 16) 
echo "RANDOM return $? , index is $index" 
done 

注意了,我这样做,以显示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

不要使用'expr'进行算术运算;使用'index = $(($ RANDOM%16))'。 – chepner

回答

7

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

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

expr命令返回的1状态如果表达式的结果为空或0,所以你会得到的1状态时$RANDOM % 16为0(时为6.25%)。

% expr 1 % 16 ; echo "\$?=$?" 
1 
$?=0 
% expr 0 % 16 ; echo "\$?=$?" 
0 
$?=1 

如果你做set -e和要执行的可能失败而不终止外壳的命令,可以追加类似|| true。由于将||的前缀用作条件,故障只会使条件成为假。

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