• POSIX shell aka /bin/sh is bash on OS X, while it’s dash on Debian, busybox ash on Alpine, etc.

      The OP makes this claim, which I’m saying is not really true in a practical sense:

      That means you can run your program on a wide range of hosts, from a Linux virtual machine, to a BSD server, to a Mac laptop, to a tiny single-board computer

      As an analogy, imagine if there was no such thing as JavaScript. Imagine you wrote v8 code (Chrome), or you wrote SpiderMonkey code (Mozilla), or you wrote Opera browser code.

      That more accurately describes the situation with Unix shell. It is not as standardized as JavaScript, basically because there is not that much industry motivation do make it so.

      And not just shell – it’s all the utilities that shell calls, which you need to get things done.


      score 1 · canonical

      • And not just shell – it’s all the utilities that shell calls, which you need to get things done.

        I think this is a very important point. Most shell interpreters are dependent on an externalised modularity—even zsh provides very minimal builtin functionality (and zsh’s modules don’t add that much more); as a result, we are dependent on external binaries. I once wrote a simple web framework in pure zsh as a gimmick, and it was a gimmick (unlike in Python, where this would work have been considered very pedestrian,) simply because shell scripting is so limited for many common tasks.

        As a result, almost any interesting shell script (whose motivation reaches even a little bit beyond the managing processes) is going to be reliant on the surrounding environment. While POSIX does specify available “utilities”, the list isn’t very long, and there are a lot of common modalities (e.g., chown --reference) that are not mandated.

        So, sure, a very simple shell script may run anywhere, but it’s unlikely that it will be able to do anything useful, unless you bootstrap an environment and standard library around it, at which point you might as well deploy a Janet statically-linked executable.


        score 2 · canonical

      • I understand the pain points when it comes to trying to adhere to POSIX. I don’t do it myself. I think shell differentiation is good. I think the benefits of non-standard features outweigh portability.


        I think there might be something in your example that is clear to you but not to me. The last line claims that POSIX doesn’t save you but if you opt into POSIX it does, even in bash.

        What I was envisioning, bash invoked as /bin/sh behaves like the other shells you mentioned:

        /bin/sh --version
        GNU bash, version 3.2.57(1)-release (arm64-apple-darwin26)
        Copyright (C) 2007 Free Software Foundation, Inc.
        
        /bin/sh -c "echo 'a\nb'"
        a
        b
        

        It’s somehow detatched from the actual POSIX opt-in behavior though because:

        /bin/bash --posix -c "echo 'a\nb'"
        a
        b
        

        score 1 · canonical

        • lobsters__andyc@crustaceanson.theshelf.topM
          link
          fedilink
          arrow-up
          1
          ·
          edit-2
          14 days ago

          That is not what I get on my Debian machine! Further adding to the confusion :-)

          $ /bin/bash --posix -c "echo 'a\nb'"
          a\nb
          
          $ /bin/bash --version
          GNU bash, version 5.2.15(1)-release (x86_64-pc-linux-gnu)
          
          $ /bin/sh -c "echo 'a\nb'"
          a
          b
          

          That doesn’t surprise me, because POSIX does not specify which one is right. bash is POSIX-compatible and dash (/bin/sh on Debian) is POSIX-compatible, in this respect, and they are incompatible/contradictory behaviors.

          I think you are on OS X because your /bin/sh is the last GPLv2 version of bash, 3.2.57, which is ancient.

          So apparently bash 3 and bash 5 have incompatible/contradictory behaviors, and both are POSIX-compatible. POSIX doesn’t help you!


          Just to prove the point more, here’s a Red Hat machine:

          $ /bin/sh -c "echo 'a\nb'"
          a\nb
          
          $ /bin/sh --version
          GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)
          

          Red Hat uses bash as /bin/sh, and it behaves differently than Debian which uses dash as /bin/sh.

          i.e. /bin/sh being “POSIX” is a weak guarantee, not something most people want to rely upon.


          score 2 · canonical

            • Your link doesn’t support that. I’m saying that if you have the script

              #!/bin/sh
              echo 'a\nb'
              

              Then you will get different behavior on Red Hat and Debian, because on Red Hat /bin/sh is bash, and on Debian it’s dash.

              Are you saying that one of Red Hat and Debian is not POSIX, or not “proper Unix”?

              If so, you are mistaken. POSIX allows both behaviors, which someone pointed out to me here:

              https://news.ycombinator.com/item?id=48711403 - comments on “POSIX is not a Shell”, which I linked in my first comment

              Looking at https://pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html#tag_20_37_05

              POSIX says:

              It is not possible to use echo portably across all POSIX systems unless both -n (as the first argument) and escape sequences are omitted.

              So POSIX is saying that the problem is with the shell script echo 'a\nb', not with dash or bash.

              The author of the shell script has to change their code to make it POSIX-compatible. It’s not dash or bash that need to change.

              And Apple does not need to patch bash, for this reason.


              score 1 · canonical

              • Are you saying that one of Red Hat and Debian is not POSIX, or not “proper Unix”?

                Almost. I’m saying that the default bash behavior that Red Hat ships is:

                • Irrelevant to POSIX (which I understand is part of your point).
                • Is not UNIX, at least by the definition of OG

                Then you will get different behavior on Red Hat and Debian, because on Red Hat /bin/sh is bash, and on Debian it’s dash.

                Yes. I agree with that. Someone also pointed out in this thread that echo is not what POSIX-adherants use, for the same reason as noted in that HN thread. POSIX doesn’t help you because it doesn’t claim to help you.

                My comment re: the UNIX certification was only in relation to my experience on Apple. You’re right that they didn’t need to patch it to satisfy POSIX. They needed to do it to satisfy OG. It’s not that bash changed between v3 and v4 or v5. It’s that bash v3 on macOS does not work the same as bash v3 on linux.

                podman run --rm -it --entrypoint /usr/local/bin/bash docker.io/bash:3 --posix -c "echo 'a\nb'"
                a\nb
                
                podman run --rm -it --entrypoint /usr/local/bin/bash docker.io/bash:4 --posix -c "echo 'a\nb'"
                a\nb
                
                podman run --rm -it --entrypoint /usr/local/bin/bash docker.io/bash:5 --posix -c "echo 'a\nb'"
                a\nb
                

                It looks like their patch wasn’t so much a source patch as likely defining:

                config.h.in
                68:/* Define DEFAULT_ECHO_TO_XPG if you want the echo builtin to interpret
                69-   the backslash-escape characters by default, like the XPG Single Unix
                70-   Specification V2 for echo.
                71-   This requires that V9_ECHO be defined. */
                72:#undef DEFAULT_ECHO_TO_XPG
                

                score 1 · canonical