I'm on Debian GNU/Linux 9. I know /proc is special, I know what /proc/self is.
This command
sh -c '/bin/cat /proc/self/comm - </proc/self/comm'
yields
cat
sh
The pattern will be similar if I use dash instead of sh. But with bash, ksh or zsh the result is
cat
cat
Taking /proc/self/stat instead of /proc/self/comm I can confirm the two cat-s are in fact the same single process. Apparently shells differ under the hood, it's OK. Now let's take
sh -c '/bin/cat /proc/self/environ - </proc/self/environ'
Having observed the above, with sh or dash I expect to see the environment of the cat first, the environment of the shell later. It seems to work (both environments are most likely identical anyway so it's hard to tell if everything works as expected, but my point is: neither environ is empty).
With bash, ksh or zsh I expect to see the environment of the cat twice, but it's only printed once. Splitting into two separate cases:
bash -c '/bin/cat - </proc/self/environ'prints nothing, as ifenvironwas empty;bash -c '/bin/cat /proc/self/environ'prints something as expected.
What is going on? This is not the case with comm or stat. Why is environ different?
$ uname -a
Linux barbaz 4.9.0-6-amd64 #1 SMP Debian 4.9.88-1 (2018-04-29) x86_64 GNU/Linux
zshandksh93would runcatin the same process (no need to fork as it's the last command in the inline script).bashdoes it only when the inline script has only one command and without redirections (comparebash -c pswithbash -c 'true; ps'orbash -c 'ps < /dev/null'). IIRC Some versions ofdashhad the same optimisation but that was reverted as it was bogus. – Stéphane Chazelas Jun 10 '21 at 13:27