Question: What resources exist for portable shell programming? The ultimate answer is to test on all targeted platforms, but that's rarely practical.

The [POSIX / Single UNIX specification](http://pubs.opengroup.org/onlinepubs/009695399/) is a start, but it tells neither you what the level of support of each implementation is, nor what common extensions exist. You can read the documentation of each implementation, but that's very time consuming and not completely accurate.

I seems to me that an ideal format would be some kind of community-annotated version of the POSIX spec, where each feature is annotated by its support level amongst the different implementations. Is there such a thing? Or are there other useful resources?

For example, there is [Sven Mascheck's shell portability pages](http://www.in-ulm.de/~mascheck/various/), but it's only about syntactic elements and a few built-ins, and only covers old shells. I'm looking for a more comprehensive resource.

Answer: 
Similar to [this answer](https://unix.stackexchange.com/questions/9997/resources-for-portable-shell-programming/10002#10002), try executing your script in [posh](http://packages.debian.org/unstable/posh).

Also, don't forget to set the `POSIXLY_CORRECT` environment variable to true, as this causes many programs (not only the shell) to adhere more strictly to the POSIX standards.
Today, you can usually find a POSIX shell on a system, and so that generally means you can script in the POSIX language (modulo running into compliance bugs).

The only problem is that `/bin/sh` is sometimes not a POSIX shell. And you must hard-code the `#!` line into scripts that are to behave as nice executables; you can't just ask the user to research the problem and then invoke your script as `/path/to/posix/shell myscript`.

So, the trick is to use POSIX features in your script, but make the script automatically find the POSIX shell. One way to do it is like this:

```
#!/bin/sh

# At this point, we may be running under some old shell
# we have to tread carefully.

# note how we use test rather than [ ] syntax and avoid
# depending on test with no argument producing a failure;
# i.e. "test $posix_shell".

if ! test x$posix_shell = x ; then
  # the three possible shell paths are just an example;
  # please extend as necessary.

  for shell in /usr/xpg4/bin/sh /bin/bash /usr/bin/bash ; do
    if test -x $shell ; then
       posix_shell=$shell
    fi
  done
  if test x$posix_shell = x ; then
    echo "no POSIX shell found"
    exit 1
    # or we could avoid bailing here and just fall back on /bin/sh:
    # echo "falling back on /bin/sh: cross your fingers that it works"
    # posix_shell=/bin/sh
  fi
  export posix_shell

  # plain "$@" is broken in ancient shells! 
  # I seem to recall ${@+"$@"}: not sure if that's the right trick.

  exec $posix_shell $0 ${@+"$@"}  # can we count on exec in legacy shells? 
fi

# phew, at this point in the script we have been re-executed and are
# being interpreted by some reasonably modern shell. We can use $(...)
# command substitution, and other features.

```

There are other approaches, such as code generation. Boostrap your scripts with a small script that takes a body of script files without a #! line, and adds one.

The worst possible thing you can do is to start writing entire scripts in such a way that they run on a Bourne shell from 1981. This is only necessary if you must write for a system that doesn't really doesn't have any other shell.