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 ifenviron
was 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
zsh
andksh93
would runcat
in the same process (no need to fork as it's the last command in the inline script).bash
does it only when the inline script has only one command and without redirections (comparebash -c ps
withbash -c 'true; ps'
orbash -c 'ps < /dev/null'
). IIRC Some versions ofdash
had the same optimisation but that was reverted as it was bogus. – Stéphane Chazelas Jun 10 '21 at 13:27