A while ago I was working with a system shell script and encountered a really unexpected result when I tried to do something a certain way. Below I've distilled it into a simple example. Odd shell behaviour of some sort has been discussed on this forum before, but I couldn't find it, so I hope this isn't a duplicate discussion.

Note that the first line of the script (in red) shouldn't be used literally. Replace it with paths to various Bourne-like shells to be tested.

At this point, to get the most out of this, you shouldn't read past the end of this paragraph. Just study the script above and decide what you think the output should be. Then come back and read the rest of the post. No cheating now, look at the script first.

Unexpected Behaviour

When I ran the script on "most" shells, the output was totally unexpected. It gave this:

HereVAR = Old

Note that since it prints "Here", the script does go into the do loop where VAR gets set to New. Yet upon exiting the loop, VAR is back to the "Old" value! It's as if what happens in the loop is somehow quite local, and is lost after leaving the loop. I got this weird behaviour with the following shells:

bash
sh NetBSD
ksh NetBSD
ksh OpenBSD
sh SunOS

Expected Behaviour

The output I'd expected was this:

HereVAR = New

After checking more shells, this output was produced by:

ksh93 CentOS
ksh SunOS

One conclusion is that Bourne-like shells are not consistent about this.

Question: Is the "locality" of the unexpected output intended and is it documented somewhere? I looked at some man pages a bit and didn't find anything, but maybe it's subtle or I plain missed it.

Here are a few selected quotes from man pages, which confirm what J65nko observed.

Quote:

Originally Posted by bash

Each command in a pipeline is executed as a separate process (i.e., in a subshell).

Quote:

Originally Posted by sh (NetBSD)

Note that unlike some other shells, each process in the pipeline is a child of the invoking shell (unless it is a shell built-in, in which case it executes in the current shell -- but any effect it has on the environment is wiped).

For ksh(1), I found nothing so explicit, but some implicit indications:

Quote:

Originally Posted by ksh

Job control refers to the shell's ability to monitor and control jobs, which are processes or groups of processes created for commands or pipelines.

... suggesting a pipeline is a group of processes (one for each command).

The above are examples of what I called "unexpected" behaviour. So far so good.

Now an oddity. The SunOS ksh has "expected" behaviour, but its man page says:

Quote:

Originally Posted by ksh SunOS

A pipeline is a sequence of one or more commands separated by |. The standard output of each command but the last is connected by a pipe(2) to the standard input of the next command. Each command is run as a separate process; ...