[Gllug] Bourne shell programming

Tethys sta296 at astradyne.co.uk
Sun Nov 19 13:45:10 UTC 2006


Mike Brodbelt writes:

>Now variables I set inside the loop vanish, as the pipe causes a
>subshell to be spawned, so I can't set variables in the body of my
>loop that are visible to the rest of the script.

Yep. It's the single most annoying feature of shell scripting[1].
If you're using bash or zsh, you can get around it by using process
substitution:

	while read x
	do
		some stuff
	done < <(grep root /etc/passwd | awk -F: '{print $1,$2,$3}')

If you're using a traditional Bourne or Korn[2] shell, it's slightly
trickier, and you need to use some form of IPC to send the values
of the relevant variable back to the parent shell. One obvious way
is simply to write the relevant information to a temporary file in
the subshell and then read the value back in the parent:

	tmpfile=$(mktemp /tmp/mytmpfileXXXXXXXXX)
	trap '/bin/rm -f "$tmpfile"' 0 INT HUP QUIT TERM

	grep root /etc/passwd | awk -F: '{print $1,$2,$3}' | while read x
	do
	    myvar="some value or another"
		echo "$myvar" > "$tmpfile"
	done

	myvar=$(cat "$tmpfile")
	echo "Myvar: $myvar"

It's crude and ugly, but it works. You can, of course, use multiple
temporary files if you have multiple values to return (which is even
more ugly, but easier than trying to multiplex multiple values into
a single file).

Tet

[1] I know the historical reasons for it behaving this way, but what
    I don't understand is why modern shells still do it. Sure, offer
    the traditional way via a shell option. Hell, even make it the
    default if you're that paranoid. But at least give the user the
    chance to select sane behaviour somehow. And indeed, I'd make the
    sane behaviour the default, and only offer insanity to those that
    explicitly request it in order to preserve backward compatibility.

[2] While Korn shell offers process substitution, sadly it doesn't
    allow it in conjunction with redirection :-(
-------------- next part --------------
-- 
Gllug mailing list  -  Gllug at gllug.org.uk
http://lists.gllug.org.uk/mailman/listinfo/gllug


More information about the GLLUG mailing list