3

This:

woof() {
        /usr/bin/woof -p $(expr $RANDOM % 32768 + 1024) $@
}

Always returns same number for parametr -p on zsh. In bash $(...) is evaluated on every call. Replacing $( ... ) with $[ ... ] 'fixes' this 'problem' in zsh for me but what is the issue or difference that causes unexpected behavior (unexpected for me at least)?

korda
  • 178
  • 5

1 Answers1

5

$( ) actually behaves the same way, it's the RNG which does not.

It seems that the zsh RNG is only advanced after referencing the value, but not reseeded when forking. This means subshells will just keep inheriting the old seed from the parent, as any changes happening in a subshell do not affect the parent process. Using $[…] does not have this problem as it doesn't create a subshell.

According to the zshall(1) manual page:

   RANDOM <S>
          A pseudo-random integer from 0 to 32767, newly generated each time
          this  parameter is referenced.  The random number generator can be
          seeded by assigning a numeric value to RANDOM.

          The values of RANDOM form an intentionally-repeatable  pseudo-ran‐
          dom sequence; subshells that reference RANDOM will result in iden‐
          tical pseudo-random values unless the value of  RANDOM  is  refer‐
          enced  or  seeded  in the parent shell in between subshell invoca‐
          tions.

Test:

% echo outer=$RANDOM; (echo inner=$RANDOM); (echo inner=$RANDOM);
outer=10246
inner=5606
inner=5606
grawity
  • 501,077