#! /usr/bin/env considered harmful - Programming On Unix

Users browsing this thread: 1 Guest(s)
jkl
Long time nixers
venam
Administrators
This is highly informative.
Next week podcast is about "default programs", I've added the subtitle: "Welcome to hell, choose your default program!".

I've only scrapped the subject so far, just prior knowledge, but it's not looking good, it's a mess.
z3bra
Grey Hair Nixers
That space between the bang and path is bothering me...
IMO, the only VALID bang you should rely on is #!/bin/sh. Every single bit of it is defined by POSIX, and is made for portability.
josuah
Long time nixers

On android, #!/bin/sh does not even works, as there is no /bin at all.

Such a bad OS for command line, but the projects for pocketable devices running linux are so rare these days!

Alternative is to build its own with a raspberry.

Useful article, as I was not aware of these issues.
robotchaos
Long time nixers
@josuah, what about tizen?

EDIT: taking this off topic...

I wish my corp firewall didn't block github. I'd really like to read this. Will read it soon though
jkl
Long time nixers
(14-09-2016, 01:36 PM)z3bra Wrote: That space between the bang and path is bothering me...

It's debatable if it was actually added intentionally or if it just "slipped through" in the affected BSD versions.
pranomostro
Long time nixers
> Not the right interpreter is found

Generally we then have to ask for the better alternatives. If we specify a path, we can never be sure it works (because none of this shit is standartized, except the location of /usr/bin/env).

> No dependencies or modules

I can't say anything about that since the most things I use scripting for is either rc or lua, where I don't happen to need modules or dynamically linking libraries. Someone smarter than me comment on this please.

> no flags

This is really stupid. This is one of the stupid unix limitatians I talked about, things that don't make any sense today but are still included.
But it applies to other shebangs as well, so I would say fuck that.

> wrong configuration of $PATH

Then your user is a moron and it is his own fault. $PATH should never be changed, only appended to.

The solutions given are both bloated and unportable. env seems like the cleaner solution to me. I don't like using tho whole path since people thought it would be a good idea to put binaries into different directories. Ugh.
robotchaos
Long time nixers
i) correct interpreter indeed. If you are on a shared server and are setting up a cron job that uses the absolute path to the python binary /usr/bin/python2.7, can you even still be sure that the executable is the one intended to complete the job? Or does shebanging absolutely give you checksumming powers?

ii) https://www.python.org/dev/peps/pep-0370/

iii) byoi(nterpreter)

iv) no flags? fine, don't use shebang on interpreted scripts. $ /usr/bin/python2.7 -RE ~/myscript

v) manage $PATH -- I fail to see the problem

vi) I feel like #!/usr/bin/env is suitable in the most properly configured environments; and in that case, more suited

Good read though :)
z3bra
Grey Hair Nixers
(14-09-2016, 05:34 PM)josuah Wrote: On android, #!/bin/sh does not even works, as there is no /bin at all.

Android is not a POSIX Operating System, that's why :)
TheAnachron
Members
I actually agree with pranomostro. That article also seems to be mosty linked to Python.
I use #!/usr/bin/env very often. It makes the user flexible to do as he wish.
If he messes this one up, it's not up to the programmer.
z3bra
Grey Hair Nixers
(14-09-2016, 08:59 PM)pranomostro Wrote: > Not the right interpreter is found

Generally we then have to ask for the better alternatives. If we specify a path, we can never be sure it works (because none of this shit is standartized, except the location of /usr/bin/env).

Some path are standardized by POSIX, like /bin/sh. env(1) location is not defined by POSIX. All it does is that it will run the 'utility' using the current environment, which is supposed to has the $PATH variable set correctly. One could technically just implement the shebang to search 'utility' in the PATH, which would allow things as "#!sh".

(14-09-2016, 08:59 PM)pranomostro Wrote: > No dependencies or modules

I can't say anything about that since the most things I use scripting for is either rc or lua, where I don't happen to need modules or dynamically linking libraries. Someone smarter than me comment on this please.

I'm not especially smarter than you are, but as far as I understand this point, it present corner cases where the same 'utility' appear multiple times in the PATH, at multiple locations. That's the same as you 3rd point.

(14-09-2016, 08:59 PM)pranomostro Wrote: > no flags

This is really stupid. This is one of the stupid unix limitatians I talked about, things that don't make any sense today but are still included.
But it applies to other shebangs as well, so I would say fuck that.

This is, again, implementation specific. And while it MIGHT be the case, it has never been actually experienced (see http://www.in-ulm.de/~mascheck/various/shebang/). What's true though, is that the shebang line is limited, and this limitation is (again!) implementation specific. I've personally been using "#!/bin/sed -f" or "#!/bin/sh -ex" happily for quite some times now.

(14-09-2016, 08:59 PM)pranomostro Wrote: > wrong configuration of $PATH

Then your user is a moron and it is his own fault. $PATH should never be changed, only appended to.

The solutions given are both bloated and unportable. env seems like the cleaner solution to me. I don't like using tho whole path since people thought it would be a good idea to put binaries into different directories. Ugh.

The exact problem mentionned is "The fifth and worst problem is that your script is at the mercy of the user’s environment configuration.".

THAT IS THE FUCKING POINT OF THE env(1) UTILITY! Of course it will use the environment of the user BECAUSE THAT'S FUCKING WHAT YOU'RE ASKING FOR. "#!/usr/bin/env bash" means "run 'bash' within the current environment. So it's freaking stupid to discuss this point as it would be like complaining about planes not touching the ground all the time.


Regarding this whole topic, the shebang is a nifty feature provided by some kernels to hack around the fact that some executables are NOT executable by a machine. You shouldn't expect much about it, but you can have enough confidence in it to use it (It's kind of like relying on bash(1) to be installed everywhere in the end).

By nature, the shebang is not portable, for the simple reason that it's not standardized:

http://pubs.opengroup.org/onlinepubs/969...hap02.html Wrote:If the first line of a file of shell commands starts with the characters "#!", the results are unspecified.
Halfwit
Members
Heh, I like using something like
Code:
#!/bin/sh

py(){
    python - <<<CODE  
        import foo
        print('This will work')
    CODE
}

py

My use of python is generally very limited, though. You can always specify version this way, as you're literally passing a heredoc to the python interpreter; you can call whichever interpreter in your path you require, or /usr/bin/python3.4 if you so desire.

edit - formatting is messed up, heh.