1. 54

  2. 14

    There is another – IMHO better – reason to avoid using flags to a hashbang: you can never be sure it’s actually picked up. Using ruby file.rb is just as valid as ./file.rb, and will not pick up on the hashbang. This is a big deal especially in cases where the flags affect program logic, like sh -e or sh -u.

    It’s almost always better to set the flags in the program itself if possible, for example set -e in shell scripts. I don’t know if that’s possible for --enable-jit --verbose in Ruby (probably not?), in which case I find it’s often better to use a run.sh wrapper script to avoid confusion down the road:

    exec ruby --enable-jit --verbose program.rb
    1. 1

      I believe that scripts should be viewed as self-contained programs, should be run as ./scriptname, and shouldn’t have the file extension. One doesn’t run ./cat.elf, right?

      So, I disagree with those two usages being valid. If one ran an ELF executable through some emulator that decided to ignore parts of it, would one complain that the script was wrong, or the emulator?

      1. 2

        You can play some tricks if you really want things to be self-contained: re-exec to same script from Ruby if the argument list doesn’t contain the wanted flags, or pipe the code to stdin from the shell script. They seem way more convoluted than just running a wrapper script though, and for most purposes it doesn’t matter all that much.

        I disagree with those two usages being valid.

        I’m not even sure how to reply to that. It solves a real-world problem that I’ve seen several times. How is that “not valid”? 2+2=99 is invalid. Just because you don’t think it’s a good trade-off doesn’t mean it’s “not valid”.

        If one ran an ELF executable through some emulator that decided to ignore parts of it

        This is an unlikely and obscure scenario. Typing ruby file.rb isn’t.

        1. 2

          If one is distributing a program for others to execute, the interface for that is ./program.

          1. 1

            This is not constructive. People type ruby file.rb all the time. And yes people use those .rb exensions regardless of what your opinion of it may be. Ignoring that is just ignoring reality.

      2. 1

        I found the best(?) of both worlds: https://rosettacode.org/wiki/Multiline_shebang#Ruby

      3. 6

        It’s actually available in coreutils 8.30

        1. 2

          Thanks! I misunderstood the GitHub commit page. I fixed the version and updated the link to point to the release notes on Savannah.

        2. 4

          Seems like the actual right solution is for the POSIX spec to say how to correctly handle shebangs.

          1. 3

            When POSIX (or any standard) fails to specify an important detail like this, it’s generally because two or more implementations already have incompatible behaviours, and those implementations refuse to change because existing users of each implementation already depend on that behaviour.

            The way to break the stalemate is to introduce a new interface with a standard behaviour (see all the posix_* functions in libc) or to standardise an existing portable workaround (like the -S switch the article mentions).

            1. 7

              Or to have an effin’ spine, deprecate one behavior (flip a coin to choose which if you must), and get on with life. Then in 20 years or so when the plug is finally pulled on the last POSIX 20XX system, everyone can heave a sigh of relief and toss it into the bin of history along with K&R C, glibc 5, python 2, OpenGL 1.2, MUMPS, and so on. It will live on in weird obscure corners of institutional systems, and those few versed in the dark arts of that particular version will never lack for gainful employment, but by and large the rest of the world can just get on with life on the assumption that they’ll never encounter the old stuff and can design sane systems. WITHOUT needing to remember the ten million fiddly, context-specific rules necessary to just make something not fundamentally horrible in some secret way.

              I know, I know. Look, I can dream, right?

          2. 4

            That was a nice read! It also reminded me of an article about how Linux 5.0 broke how shebangs are used by Nix:


            1. 3

              My favorite part of that is that perl “magically” corrects its own shebang. Which is kind of nuts and helps propagate broken things.

              1. 2

                What broken things? The Linux kernel used to truncate the shebang path to 128 characters, and Perl worked around that. Maybe other unixes did too, while yet others did not. Perl is designed to work on all of them, and on other platforms too.

                Edit I remember researching this at the time


            2. 2

              Interesting. env -S is unsupported on my DragonFly boxes but works on my Macbook. Chalk another one up for the wonderful world of unix support.

              1. 2

                OpenBSD doesn’t support env -S either.