I have some troubles getting a good understanding of the way Bash manages sub-shell creation and the related scoping issues. Hope someone can bring some coherence to my thoughts on this matter.
The first thing I don't get is the way variables are handled in sub-shells. I thought variables weren't inherited, unless they had the eXport flag on. However this doesn't seem to be true for sub-shells created by grouping:
$ n=3 $ ( pstree $$ ; echo $n ) bash---bash---pstree 3 If, instead, I create the sub-shell manually everything goes as expected:
$ export ppid=$$ $ bash $ pstree $ppid bash---bash---pstree $ echo $n Also some grouping doesn't actually create a sub-shell:
( pstree $$ ) bash---pstree And some grouping that shouldn't, in fact does:
$ pstree $$ & [1] 1685 $ bash---pstree { pstree $$; } & [1] 1687 $ bash---bash---pstree This seems a bit messy to me, with a lot of special cases to keep track of. And it gets more messy. Consider process substitution:
$ cat <(pstree $$) bash-+-bash---pstree `-cat Here, for what is my understanding, bash executed cat in a sub-process, giving it a FIFO to read from. Then forked a sub-shell giving it the other end of the FIFO. The sub-shell ran pstree.
Consider now:
$ pstree $$ > >(cat) # There is some non determinism involved, output may be different bash---pstree---bash---cat #or sometimes bash---pstree---bash Here bash seems to do something different. It forks a sub-shell, the sub-shell forks another sub-shell, and the situation become: bash---bash(1)---bash(2)
bash(1) (which got the write end of the FIFO) execs pstree and bash(2) (with write end of the FIFO) runs cat in a sub-process.
So in the first case the sub-process gets executed by a sub-shell of the primary shell. In the second by a shell sub-process of the primary command.
In my opinion the 2nd case is because pstree may run before cat is created.
pstree $$ > >(cat)?$$will the not be updated for subshells. Use$BASHPIDinstead.> >(...), see this.(pwd)is identical topwd, because bash optimizes(pwd)to(exec pwd). c) there isn't any grand design principle behind the shell language, its operations grew "organically", and they're not always consistent.