20

I have read that POSIX compliant operating systems (for example: Linux) must have the sh shell.

But is it required for sh to be in the /bin directory, or can it be in any directory?

  • You can always use a symlink as /bin/sh, in most cases on linux, it's already a symlink to bash. It's just that lots of scripts use hardcoded /bin/sh – cylgalad Jan 13 '18 at 09:11
  • 6
    Now that you have the answer that it can live anywhere it wants, you may ask yourself: how can you then portably write a shebang line for sh? And the answer is: shebang isn't part of POSIX either, so the problem doesn't even present itself. – Jörg W Mittag Jan 13 '18 at 09:30
  • 1
    @JörgWMittag Yes, it's sometimes surprising how many of the things we think of as "standard" Unix features are not actually required by POSIX. – Barmar Jan 13 '18 at 17:54
  • 1
    Whether or not you use a shebang is independent of whether the path /bin/sh must exist on a POSIX system. – chepner Jan 13 '18 at 19:13
  • At least on Ubuntu-derived systems, /bin/sh is a link to dash. On the BSDs, /bin/sh is its not a link but a separate executable, and certainly not bash. – Rhialto supports Monica Jan 13 '18 at 20:11

3 Answers3

24

POSIX only mandates the /dev and /tmp directories to exist, and the /dev/null, /dev/tty, and /dev/console files. The standard utilities must exist, but there is no particular location specified. There may not be a /bin at all, and if there is it may not contain a sh, and if it does that may not be a POSIX sh.

You can get a valid PATH variable that includes the POSIX tools, including sh, with the getconf command:

$ PATH=$(getconf PATH)
$ sh

This can be useful on, for example, Solaris, where the default sh is not POSIX-compatible, but a compliant sh is provided and accessible in that way (because Solaris is a certified Unix). getconf PATH will include /usr/xpg4/bin at the front, which contains POSIX sh and a number of other required tools (including useless ones like cd).

Michael Homer
  • 76,565
  • Re Solaris: ...unless you're running a Solaris "small server" installation, which omits many of the POSIX tools. See https://unix.stackexchange.com/q/360359/135943 – Wildcard Jan 13 '18 at 03:11
  • "Useless" ones? I'd rather call them redundant. – Mukesh Sai Kumar Jan 13 '18 at 08:37
  • 2
    so how is getconf found? – Joshua Jan 13 '18 at 15:03
  • @MukeshSaiKumar a stand-alone ‘cd’ command cannot ever work – OrangeDog Jan 13 '18 at 17:03
  • Well, it'll "work" only for a value of working that, say, tests whether you can change to a directory, but doesn't actually leave the process that called it there. That's more functionality than none at all, though. – Charles Duffy Jan 13 '18 at 17:05
  • @Joshua Hopefully it’s already in your path. In practice it is, because that’s useful, and there’s no historic command with the same name to be shadowed. – Michael Homer Jan 13 '18 at 17:37
  • Note that on Solaris, you will get different values of PATH back depending on which getconf you call. Which one you call (for example /usr/xpg4/bin/getconf) will determine what type of standard shell utilities you get access to. – Kusalananda Dec 12 '18 at 17:24
12

No, it is not required for sh to be in /bin. It explicitly cites /bin, /usr/bin, and /usr/xpg4/bin as possible locations. The POSIX spec only requires that sh be in the PATH.

The POSIX spec states:

Applications should note that the standard PATH to the shell cannot be assumed to be either /bin/sh or /usr/bin/sh, and should be determined by interrogation of the PATH returned by getconf PATH, ensuring that the returned pathname is an absolute pathname and not a shell built-in.

For example, to determine the location of the standard sh utility:

command -v sh

On some implementations this might return:

/usr/xpg4/bin/sh

John1024
  • 74,655
3

As others here have said, this is not strictly required for POSIX compliance.

But arguably compatibility with existing software is far more important (after all, the purpose of POSIX is to have certain things work on all conforming operating systems) and if an OS does not provide sh at /bin/sh, that will break some things.

Most obviously, scripts with #!/bin/sh rely on this path being standardized. This is not required to work; POSIX doesn't even require that #! lines are supported, although it mentions that such functionality is common:

Another way that some historical implementations handle shell scripts is by recognizing the first two bytes of the file as the character string "#!" and using the remainder of the first line of the file as the name of the command interpreter to execute.

But if that isn't supported, a lot of existing software will break or require additional work to port.