Configuration Information [Automatically generated, do not change]: Machine: i686 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='i686' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i686-pc-linux-gnu' -DCONF_VENDOR='pc' -DLOCALEDIR='/usr/local/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I. -I./include -I./lib -g -O2 uname output: Linux tjanouse.englab.brq.redhat.com 2.6.18-8.1.8.el5 #1 SMP Mon Jun 25 17:06:19 EDT 2007 i686 i686 i386 GNU/Linux Machine Type: i686-pc-linux-gnu
Bash Version: 3.2 Patch Level: 25 Release Status: release Description: If you cause rng to be seeded in a subshell (enclose the command in parentheses) and in this same subshell spawn another subshell, rng is not seeded as it should be. See the example in Repeat-by. Repeat-By: $ ( echo $RANDOM; ( echo $RANDOM ); ( echo $RANDOM ) ) 28804 3664 3664 Fix: We had a fix in the Fedora package that used subshell_level instead of just looking at subshell_environment, but that introduced another oddity, since subshell_level is not increased for simple async commands. (bugzilla for this one is https://bugzilla.redhat.com/show_bug.cgi?id=344411 ) I'm attaching a patch that was applied over that one, so it just shows what the final solution is like, it's not applicable to 3.2 tarball. -- Tomas Janousek, SW Engineer, Red Hat, Inc.
344411: $RANDOM stays the same when job executed in the background In bash 3.0, random was seeded whenever subshell_environment != 0. In bash 3.2, random was seeded whenever subshell_environment != 0 && seeded_subshell == 0. And when it was seeded, seeded_subshell was set to 1. Therefore, in 3.2, if you seeded random in a subshell and in this subshell invoked another one, it wasn't reseeded as it should have been. A testcase for that is this: ( echo $RANDOM; ( echo $RANDOM ); ( echo $RANDOM ) ) Tomas's patch (bash-3.2-rng.patch) changed the code to use subshell_level. subshell_level is not increased for simple async commands, however. So, although he fixed the previous case, he introduced another. Here's a testcase: echo $RANDOM; echo $RANDOM & echo $RANDOM & I decided to just compare the pids, that should be safe enough. Written-by: Tomas Janousek <[EMAIL PROTECTED]> Reviewed-by: Tomas Mraz <[EMAIL PROTECTED]> --- bash-3.2/variables.c.344411 2007-11-06 19:26:42.000000000 +0100 +++ bash-3.2/variables.c 2007-11-06 20:27:25.000000000 +0100 @@ -1211,7 +1211,7 @@ arrayind_t unused; { sbrand ((unsigned int)strtoul (value, (char **)NULL, 10)); - seeded_subshell = subshell_level; + seeded_subshell = getpid(); return (self); } @@ -1221,10 +1221,10 @@ int rv; /* Reset for command and process substitution. */ - if (seeded_subshell < subshell_level) + if (seeded_subshell != getpid()) { seed_random (); - seeded_subshell = subshell_level; + seeded_subshell = getpid(); } do