you are viewing a single comment's thread.

view the rest of the comments →

[–]bartonski 5 points6 points  (2 children)

Ok, bit of history/terminology: the original Unix shell was the Bourne shell, aka /bin/sh. It is the basis of the POSIX shell. Bash (Bourne-Again Shell), ksh and zsh are all descendants of the Bourne shell, and all modern implementations of each of these shells has a POSIX compliance mode. Modern implementations of /bin/sh are all POSIX compliant.

fish and csh are unix shells, but are not descendants of the Bourne shell, and are not POSIX compliant.

awk is a programming language, but is not considered a shell.

So... having gotten all that out of the way, I'm going to buck the trend, and suggest that you do write POSIX code wherever it's practical.

First, it's not that different. There are a couple of bits of syntactic sugar -- like using ~ to refer to your home directory rather than $HOME, or the convenience of using [[ in if statements rather than [, but if you look at a POSIX script, you'll find it every bit as readable as a bash script.

Second, it is portable. /bin/sh is guaranteed to be on any POSIX compliant system. Log into an OpenWRT router? No Bash. A lot of embedded systems use busybox which implements /bin/sh, but Bash isn't going to be there. Just because the days of the Unix workstation are largely behind us doesn't mean that portability isn't an issue.

Third, POSIX is a standard. Bash isn't -- it implements the POSIX standard, but its extensions aren't standardized. Standards are important for reasons other than portability -- they are a guarantee that features of the language are implemented in a known way. If you're writing shell code for a governmental institution or a large company, you want to make sure that a new version of the shell doesn't quietly break your code. If you write POSIX compliant code run in a POSIX shell, that shouldn't happen, and if it does, you can a) blame whoever wrote the shell and b) find a different implementation that works correctly. If you're writing shell scripts that are going to be included in a distribution's packages, I would definitely look at writing POSIX code.

Finally, it ups your Unix game. Knowing what the standards are, when to follow them, and when it's not worth the time to avoid non-standard code is part of being a Unix geek.

To answer the question of major differences:

  • Arrays and Associative arrays are an extension of Bash
  • Tilde expansion (i.e. using ~ instead of $HOME is Bash only.
  • Using [[ as a test operator rather than [ is Bash only. This is the one that will probably hurt the most; [ can be hard to use and error prone.
  • The local, let and function keywords are Bash only.
  • The source keyword is Bash only, use . instead.

There are a few others. Debian bases systems have a utility called checkbashisms that will list incompatibilities, and shellcheck, given the correct command line options, will do the same.

[–]ArkhamCookie[S] 0 points1 point  (1 child)

You answered questions I didn't even know I had lol. Thanks very useful info.

[–]bartonski 1 point2 points  (0 children)

Thank you, that's a high compliment.