17

When I run a Centos 7 Docker Image like this

docker run -it centos:7 bash

Running something which is uses Process Substitution is fine (as expected, as Bash supports Process Substitution since the beginning of time - Bash 1.4.x actually).

For example:

while IFS= read -r test; do echo $test; done < <(cat anaconda-post.log)

But when I switch to /bin/sh the same code doesn't work anymore

/bin/sh
while IFS= read -r test; do echo $test; done < <(cat anaconda-post.log)
sh: syntax error near unexpected token `<'

Although /bin/sh seems to be Bash

/bin/sh --version
GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

But then why doesn't process substitution work anymore? Other non-POSIX features seems to work, though

echo ${PATH//:/ }
/usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin
8
  • 3
    Either way, you don't have use process substitution at all. Just use input redirection, while IFS= read -r test; do echo $test; done < anaconda-post.log
    – Inian
    Sep 9 at 6:08
  • 5
    Note that you seem to have invoked /bin/bash --version instead of /bin/sh --version.
    – Kusalananda
    Sep 9 at 6:44
  • 1
    I cannot reproduce your example using centos:7 (8652b9f0cb4c).
    – muru
    Sep 9 at 7:04
  • 1
    @ImHere 4.2.46(2)-release (x86_64-redhat-linux-gnu).
    – muru
    Sep 9 at 8:20
  • 11
    Don't use bashisms if you use /bin/sh. Or don't use /bin/sh if you want to use bashisms. - "Although /bin/sh seems to be Bash" - Never rely on that; it may work now, but it may not work in the future, or on another system.
    – marcelm
    Sep 9 at 15:30
32

Yes, bash, when called as sh, runs in POSIX mode, disabling all its bash only features. From the manual - Invoked with name sh

If Bash is invoked with the name sh, it tries to mimic the startup behavior of historical versions of sh as closely as possible, while conforming to the POSIX standard as well

$ ls -lrth /bin/sh
lrwxrwxrwx. 1 root root 4 Aug 26  2018 /bin/sh -> bash
$ /bin/bash -c 'set -o | grep posix'
posix           off
$ /bin/sh -c 'set -o | grep posix'
posix           on

with posix mode enabled, non-standard features like process substitution won't be enabled. See Bash POSIX Mode to see its complete behavior running in the mode.

From release 5.1 of the shell, process substitutions are available in POSIX mode.

5
  • @Kusalananda ... unstable repo? Well, debian stable is bullseye, and it seems to be using 5.1 (What can I say?). The source comes from Chet anyway: ftp.cwru.edu/pub/bash
    – ImHere
    Sep 9 at 8:13
  • 1
    @Kusalananda Some attribution might be appropriate, don't you think? Now my answer is irrelevant. :-(
    – ImHere
    Sep 9 at 8:20
  • 1
    Supporting process substitution doesn't make a shell non-POSIX compliant as the behaviour for cmd <(cmd2) is unspecified per POSIX. In newer versions of bash, process substitution is not disabled when in POSIX mode (you'd still not want to use process substitution in sh scripts) Sep 9 at 12:19
  • 2
    In any case, bash certainly does not disable all its extensions (most of them including process substitution are copied from other shells, so not bash only) when in POSIX mode. Sep 9 at 12:20
  • 1
    unfortunately i don't remember any specific lingering feature, but it disables nearly all bash features, there are some things it doesn't actually disable (don't remember anything specific, maybe it was even a bug, hopefully someone else here knows)
    – hanshenrik
    Sep 10 at 13:39
9

Some options are disabled on bash's POSIX mode. Which gets activated when bash is called as sh. From the bash manual page:

When invoked as sh, bash enters posix mode after the startup files are read.

But in version 5.1 process substitution got re-enabled in POSIX mode

So, for present versions (you are using 4.2 from your now erased self-answer) process substitution works even if bash is called as sh.

4

What is /bin/sh? We're talking about Unix legacy here! A bit of history:

sh is the Bourne Shell, it was released in 1979 in the Version 7 Unix release. It gained popularity with the publication of The Unix Programming Environment by Brian Kernighan and Rob Pike—the first commercially published book that presented the shell as a programming language in a tutorial form.

ksh, the Korn shell originally written by David Korn, was based on the original Bourne Shell source code, it was a middle road between the Bourne shell and csh the C shell. Its syntax was chiefly drawn from the Bourne shell, while its job control features resembled those of the C shell. The functionality of the original Korn Shell was used as a basis for the POSIX shell standard.

bash is the 'Bourne Again SHell'. Bash syntax is a superset of the Bourne shell syntax. Bash syntax includes ideas drawn from the Korn Shell and the C shell such as command line editing, the history command, the directory stack, the $RANDOM and $PPID variables, and POSIX command substitution syntax $(…).

2
  • As far as I've understood, systems where sh would be the legacy Bourne shell and not some POSIX sh compatible one are rather rare.
    – ilkkachu
    Sep 10 at 13:39
  • 2
    I know, this is a historical answer; Sep 10 at 13:54
3

An additional point - on Centos 7, sh is a symlink to bash. There is no separate binary for sh .

[root@work ~]# ls -la `which sh`
lrwxrwxrwx. 1 root root 4 Jun 16  2020 /usr/bin/sh -> bash
[root@work ~]# ls -la /bin/sh
lrwxrwxrwx. 1 root root 4 Jun 16  2020 /bin/sh -> bash

[root@work ~]# rpm -qf /usr/bin/sh /bin/sh
bash-4.2.46-34.el7.x86_64

bash, dash, busybox and likely other shells can check the command line they were started with, and will pretend to be something-else like plain sh if that's how they were called. This symlink lets that happen.

You can always expect /bin/sh to be there, and to be a basic shell.

1
  • 1
    Important as downstream distros might alias it to dash. Internally bash can detect the name it was invoked as. The root account might use sh as a default shell, you can change this, but there are reasons for these things.
    – mckenzm
    Sep 9 at 23:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.