1. 9
  1.  

  2. 10

    POSIX shell, on the other hand, has many competing implementations on many different operating systems - all of which are compatible with each other because they conform to the standard.

    That’s not really true. dash and bash are incompatible in some basic ways, which are not resolved by POSIX. I list two here:

    http://www.oilshell.org/blog/2018/01/28.html#limit-to-posix

    Example:

    $ dash -c 'x="a b"; readonly y=$x; echo $y'
    a
    $ bash -c 'x="a b"; readonly y=$x; echo $y'
    a b
    

    The above is a very short POSIX shell script, but which one is right?

    dash is actually the most “divergent” shell I’ve tested. bash, mksh, and busybox ash all tend to agree on the important stuff (although they implement different features, and wildly disagree on error cases). dash has basic disagreements like this.

    Also, I mention that Debian doesn’t even limit itself to POSIX – they forked/developed dash to replace bash, but apparently couldn’t do what they wanted without some extensions like local, which I agree is essential.

    BTW, this is from my user experience, not just writing Oil. I tried to switch to dash maybe 4 years ago, but gave up because it was so incompatible (and harder to use than bash).

    1. 2

      The above is a very short POSIX shell script, but which one is right?

      You could just put double quotes around the argument to readonly and be done with it:

      dash -c 'x="a b"; readonly "y=$x"; echo $y'
      a b
      

      Yes, it’s inconsistent compared to normal assignment. Yes, it’s portable.

      Having worked on code that needs to run on multiple platforms and having had to deal with shell scripts incompatible between e.g. zsh and bash with people on either side arguing that their shell is superior, I feel that the least common denominator (POSIX) is the way to go. Pragmatic side-steps can still be made if the result is that it doesn’t cause more problems than it solves. local tends to work across shells and does solve a real-world problem.

      1. 2

        Sure, but my point is that “use POSIX”, and especially “read the POSIX spec”, is not great advice.

        That’s not the only example; I could name at least a half dozen other divergences that occur in practice, which POSIX is silent on.

        I’ve never heard anyone say “use POSIX, but make sure to quote your assignments, and … “.

        There are very few people who learn programming languages by reading specifications. Usually it’s a matter of working with an existing codebase, googling and reading StackOverflow results, reading books, etc.

        I have a whole book on POSIX shell, so I’m very familiar with this kind of advice. I just don’t think it’s useful. It’s just a big headache that very few people will follow. For example, echo vs. printf. 95%+ of shell scripts I see use echo, even though it’s not fully-specified and not portable.

        1. 1

          YMMV. Following the advice in “Beginning Portable Shell Scripting” by Peter Seebach, the Open Group base spec1 and tools like ShellCheck has worked very well for me, deploying to Slackware with /bin/sh symlinked to bash (IIRC, or maybe it was a copied binary?), Debian with dash as /bin/sh, FreeBSD with /bin/sh being an Almquist shell (ash) descendant, and running the same scripts directly in bash and zsh as well.

          I tend to stay away from csh, tcsh and I’ve never seen them being used as a /bin/sh substitute, though I would be interested in knowing if there are such systems.

    2. 6

      stick to pre-ansi c instead of c++17, this is the only way to make sure that your code will run on ancient unix platforms that died well before you were born

      1. 3

        If it wasn’t in Unix V7 it’s not worth using.