MatrixManAtYrService
MatrixManAtYrService

Reputation: 9141

Why does piping the output of $RANDOM affect the value?

Below is a script that I expect to generate the same pair of numbers three times:

#! /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

Instead, piping the output prevents the random seed from being respected. Why?

 first 18499
second 9909

 first 18499
second 9909

?????? 843
 first 18499

Ultimately, I'd like to be able do something like this:

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

What modifications can I make to the latter script so that its output is the same each time I run it?

Upvotes: 4

Views: 423

Answers (2)

Gordon Davisson
Gordon Davisson

Reputation: 125838

Since @JohnKugelman's answer isn't working for me, here's an alternative (that also has the advantage that it'll work in non-bash shells that don't support <<<). Just assign a temp variable to the result from $RANDOM, and then use the temp variable in the subshell (or other weird context):

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

echo

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

Output (under bash v4; v3 uses a different random number generator):

 first 18499
second 9909

 first 18499
second 9909

Upvotes: 1

John Kugelman
John Kugelman

Reputation: 361729

The commands in a pipeline are executed in subshells, and subshells have their own independent environment variables. $RANDOM is updated in the pipeline and this update doesn't propagate to the parent shell, which is why you see 18499 from the following echo.

In this case you can avoid a pipeline by using <<< redirection instead. Redirection does not create a child process.

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

or

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

Upvotes: 3

Related Questions