Reputation: 715
I am running the same script under Linux and under solaris. Here is the script:
#!/bin/sh
index=0
ls /tmp | grep e |
while read fileWithE
do
echo $fileWithE
index=`expr $index + 1`
done
echo "index is $index"
Since the while loop runs in a subshell, I was expecting 'index is 0' as an output in solaris and in linux. But in solaris the $index is the actual number of files containing 'e' under /tmp. So while loops don't run in a subshell under solaris? I was expecting the same results in both OS..?
Upvotes: 1
Views: 364
Reputation: 295650
POSIX doesn't require that no component of a pipeline be run by the outer shell; this is an implementation decision left to the individual shell's author, and thus a shell may have any component or no component of a pipeline invoked by the parent shell (and thus able to have side effects that persist beyond the life of the pipeline) and still be compliant with POSIX sh.
Shells which are known to use the parent shell to execute the last component of a pipeline include:
lastpipe
option enabled, when job control is disabled.If you want to be certain that shell commands run in a pipeline can have no side effects across all POSIX-compliant shells, it's wise to put the entire pipeline in a explicit subshell.
One way you can experimentally validate that this difference in behavior is related to position within the pipeline would be to modify your test only slightly by adding an additional pipeline element.
#!/bin/sh
index=0
ls /tmp \
| grep e \
| while read fileWithE; do echo "$fileWithE"; index=`expr $index + 1`; done \
| cat >/dev/null
echo $index
...you'll see that the | cat
changes the behavior, such as the changes to index
made by the while
loop are no longer visible in the calling shell even on commonly available shells where this would otherwise be the case.
Upvotes: 5