为什么用管道传递$ RANDOM的输出会影响值?

时间:2018-07-04 23:43:42

标签: bash random

下面是一个脚本,我希望它会生成三对相同的数字:

#! /usr/bin/env bash
RANDOM=5
echo " first" $RANDOM
echo "second" $RANDOM

echo

RANDOM=5
echo " first" $RANDOM
echo "second" $RANDOM

echo

RANDOM=5
echo "??????" $RANDOM | cat
echo " first" $RANDOM

相反,对输出进行管道传递可防止尊重随机种子。为什么?

 first 18499
second 9909

 first 18499
second 9909

?????? 843
 first 18499

最终,我希望能够执行以下操作:

#! /usr/bin/env bash
n=3
for i in $( seq $n) ; do
    RANDOM=5
    echo $RANDOM | md5sum | cut -d' ' -f1
done

我可以对后一个脚本进行哪些修改,以使每次运行时其输出都相同?

2 个答案:

答案 0 :(得分:3)

管道中的命令在子Shell中执行,并且子Shell具有其自己的独立环境变量。 $RANDOM在管道中进行了更新,并且此更新不会传播到父Shell,这就是为什么您从以下18499中看到echo的原因。

在这种情况下,您可以使用<<<重定向来避免流水线。重定向不会创建子进程。

cat <<< "?????? $RANDOM"

(md5sum | cut -d' ' -f1) <<< "$RANDOM"

答案 1 :(得分:1)

由于@JohnKugelman的答案对我不起作用,因此这是一个替代方案(它还有一个优势,它可以在不支持<<<的非bash shell中使用)。只需为$RANDOM的结果分配一个临时变量,然后在子shell(或其他奇怪的上下文)中使用该临时变量:

#! /usr/bin/env bash
RANDOM=5
echo " first" $RANDOM
echo "second" $RANDOM

echo

RANDOM=5
tmprandom=$RANDOM
echo " first" $tmprandom | cat
echo "second" $RANDOM

输出(在bash v4下; v3使用其他随机数生成器):

 first 18499
second 9909

 first 18499
second 9909