1. 25

  2. [Comment removed by author]

    1. 11

      GNU is a recursive acronym for “GNU’s Not Unix!”.

      1. 9

        And I’d say as someone who’s been using guix for a while, it’s largely a mistake. /usr/bin/env is probably one of the few intelligent pieces of unix filesystem hierarchy. I always just copy one back to /usr/bin/env.

        1. 6

          Author here :D - Thanks for the input.

          Did not enjoy the patronizing writing style.

          I have a lot of frustration on this topic (if you couldn’t tell), hard coded paths have given me a large number of “contributions” to various projects that I have ported to OpenBSD. It’s gotten to the point where I typically abandon the porting effort if I run into #!/bin/bash

          1. [Comment removed by author]

            1. 7

              I do have a script to do it. The problem is I either have to A) maintain a set of patch files that get applied to the port at build time, or B) I have to send a PR to the project to get it fixed upstream.

              A: Is workable, but B is a better option as it will help other projects in the same situation as OpenBSD. B: Often results in long drawn out discussions involving solutions along the lines of:

              “bash is installed in /bin on my system, why can’t you just symlink it on OpenBSD?”

              Sure this would solve the immediate problem, but as the goal is to produce a port that other people will run, I can’t go around symlinking stuff on their boxes.

              1. 6

                One problem is that I don’t have qbit’s script.

                1. 6

                  Hammer time!

                  find . -type f -exec sed -i 's$#!/bin/bash$#!/usr/bin/env bash$' {} \;
                  1. 1

                    You probably want to anchor that regular expression to the front of the line.

              2. 1

                I would love to have your problems. Sigh.

              3. 3

                Where does GuixSD keep env?

              4. [Comment removed by author]

                1. 9

                  env exists in the same place on more systems than many other interpreters.

                  The kernel, which is what interprets hashbang lines, doesn’t know what your PATH is.

                  1. 1

                    The kernel most certainly does know what PATH is. It’s in the third argument to execve.

                    1. 2

                      The environment passed to execve is opaque to the kernel.

                      1. 2

                        For perhaps some definition of opaque that I’m not familiar with:

                        • The structure is defined.
                        • The kernel knows they’re strings. Linux, OpenBSD, et al obviously need to know this otherwise they wouldn’t know how many bytes to copy.
                        • The Linux kernel also knows how to read the strings. I’m sure there’s similar stuff in OpenBSD- after all, how would pledge+env work?
                        • The Linux kernel even has an idea about what PATH should be set to.

                        Making #! examine PATH would be trivial: All the machinery is already there.

                        1. 1

                          The kernel knows they’re strings.

                          Which doesn’t make parsing them a good idea.

                      2. 1

                        PATH is a convention/convenience that your shell uses. I could write a new shell that uses BINPREFIXES instead. Should the kernel know to parse that out of execve’s env arg, too?

                        1. 3

                          It’s a bit more than a completely arbitrary shell-internal convention, since POSIX standardizes the name PATH, the specific syntax it takes, and the resulting search order, so it should be portable in any conforming implementation. It’s alongside the LC_* set of internationalization environment variables and various others, in the set of well-known environment variables POSIX decided to include in the standard. (That doesn’t mean the kernel should necessarily rely on this, but at least on systems that claim to be POSIX-compliant, I do think the kernel developers could choose to rely on it if they wanted, and simply say that if your shell doesn’t follow the POSIX standard then you can’t expect certain features to work.)

                          1. 1

                            Woah. I didn’t realize this. Ignore my ignorant comment then.

                    2. 3

                      Inertia is a very good reason. Even if we change Linux and convince ✳BSD to change, how do we get Apple to change? IBM? Oracle? HP? What about old unix systems?

                      There are also security implications in trusting environment variables when launching programs.

                      Such a change would be difficult, and need to be done carefully.

                      Meanwhile, /usr/bin/env is standardised, while bash is only /bin/bash if it was installed in a nonstandard location:

                      The official location of a default install of bash is in /usr/local/bin/bash, however a combination of the fact that many Linux distributions have popularised bash as the de-facto replacement for the POSIX shell, and the fact that the brain-damaged FHS mandates that “compliant” distributions not install software into /usr/local means there will never be one place “bash scripts” can expect to find bash.

                      1. 1

                        Security implications are one reason I’ve also heard cited for why the hashbang feature of Unix doesn’t search PATH. But wouldn’t those same security implications argue for not using /usr/bin/env either?

                        1. 2

                          I think that’s an argument against /usr/bin/env not an argument for #!search

                          A better solution is a user-controlled binfmt_misc.

                          1. 1

                            I don’t buy the argument that a full hashbang is more secure. If someone has enough access to your box to add a bin to your PATH, they can also over write builtins like if by simply creating a file named if.

                            This would impact any script no matter what hashbang it had.

                            1. 1

                              It’s possible this is shell-specific, but bash definitely defaults to builtins:

                              $ export PATH=/tmp/bin:$PATH
                              $ mkdir /tmp/bin
                              $ echo '#!/bin/sh
                              > echo Boo!
                              > echo $@' > /tmp/bin/echo
                              $ chmod +x /tmp/bin/echo
                              $ which echo
                              $ echo foo
                              $ /tmp/bin/echo foo

                              (Also it doesn’t make sense to replace if, it’s got additional syntax associated with it. It’s not just another command. I assume you meant test/[, which can be replaced.)

                              1. 1

                                It’s possible this is shell-specific, but bash definitely defaults to builtins:

                                Aliases and builtins take priority over PATH in any sane shell. [ (test) is normally an external command; ksh and derivatives have a builtin replacement, [[.

                      2. 2

                        Why not just write compliant bourne shell scripts with #!/bin/sh?

                        1. 5

                          Because those are so horrible to write, and also, if you really, truly want portability, you can’t even rely on standards. Have you seen what a GNU configure script looks like? That’s what portability looks like.

                          1. 1

                            Have you seen what a GNU configure script looks like? That’s what portability looks like.

                            No. This is what a pathological worst-case attempt of portability looks like.