Cannot pass an argument to python with "#!/usr/bin/env python"
Solution 1
It is better to use environment variable to enable this. See python doc : http://docs.python.org/2/using/cmdline.html
for your case:
export PYTHONUNBUFFERED=1
script.py
Solution 2
In some environment, env doesn't split arguments.
So your env is looking for python -u
in your path.
We can use sh to work around.
Replace your shebang with the following code lines and everything will be fine.
#!/bin/sh
''''exec python -u -- "$0" ${1+"$@"} # '''
# vi: syntax=python
p.s. we need not worry about the path to sh, right?
Solution 3
This might be a little bit outdated but env(1) manual tells one can use '-S' for that case
#!/usr/bin/env -S python -u
It seems to work pretty good on FreeBSD.
Solution 4
When you use shebang on Linux, the entire rest of the line after the interpreter name is interpreted as a single argument. The python -u
gets passed to env
as if you'd typed: /usr/bin/env 'python -u'
. The /usr/bin/env
searches for a binary called python -u
, which there isn't one.
Solution 5
Passing arguments to the shebang line is not standard and in as you have experimented do not work in combination with env in Linux. The solution with bash is to use the builtin command "set" to set the required options. I think you can do the same to set unbuffered output of stdin with a python command.
my2c
Eskil
Updated on July 08, 2022Comments
-
Eskil almost 2 years
I needed to have a directly executable python script, so i started the file with
#!/usr/bin/env python
. However, I also need unbuffered output, so i tried#!/usr/bin/env python -u
, but that fails withpython -u: no such file or directory
.I found out that
#/usr/bin/python -u
works, but I need it to get thepython
inPATH
to support virtualenv
environments.What are my options?
-
IanNorton about 12 yearsThanks, this worked well for me for another problem ( using the mono csharp shell with arguments )
-
Martijn Pieters almost 11 yearsFor those wondering how this works: Why does this snippet work?
-
user4815162342 over 10 yearsthe
${1+"$@"}
hack has probably been unnecessary for at least 20 years :) -
Ade YU over 10 years@user4815162342 Thank you for the information. I'll try
"$@"
next time. :) -
Aaron McDaid almost 10 yearsThe hack is unnecessary perhaps, but it doesn't do any harm does it? It's fun to know about it :-) I just learned about it today. Anyway, I think
"exec" "python" "-u" "--" "$0" "$@"
might be easier to understand - is there any flaw in it? (I think it's not compatible with the1+
hack?) -
Ade YU over 9 years@AaronMcDaid Since the hack is unnecessary, your version works fine and is really much more readable! Great!
-
Aaron McDaid over 9 yearsThere is a disadvantage with my method. If you want to pass something complicated to bash, such as a string with nested
'
or"
, then your method is more reliable. It's an interesting issue! Mine is easier to understand perhaps, but yours is more robust. Perhaps your answer should clarify that it must start with''''exec
, and the string must end in# '''
(with a space before the#
). As long as we follow those rules, and don't have any extra triple-quotes'''
, your method is perfect and flexible. -
wieczorek1990 over 9 yearsThis should be bundled :)
-
philwalk over 8 yearswow, it would be good if this worked widely, but also not available on cygwin :(
-
nodakai over 8 yearsSeems like the
-S
option is specific to BSD variant ofenv(1)
but it's good to know -
MartyMacGyver almost 8 yearsFYI, this does NOT work in Debian. I'm not sure why it doesn't work (to look at
ps
output there shouldn't be any difference) but it never returns. It's not very clear if python itself is actually running at all when you do this in Debian. I tried this in a few places - definitely doesn't work as expected versus the equivalent command line. -
Mad Physicist almost 8 years@MartyMacGyver. Very likely to do with the version of
env
or evenpython
you are using. -
MartyMacGyver almost 8 yearsCould be the version of env, but it's not working with any modern Debian variant thus far. It doesn't appear that Python is actually running in this scenario on Debian, making it of limited use outside certain platforms and/or configs.
-
Vladyslav Savchenko almost 8 yearsUnfortunately this way conflicts with module's docstring. Is there any way to separate that hack and module's docstring?
-
Alex Miller almost 7 yearsTo anyone reading this and feeling hopeful, the patch was abandoned.
-
akhan over 6 years@user4815162342 Here is more context on
${1+"$@"}
. So"$@"
should work fine on its own in most cases. -
akhan almost 6 yearsSo in summary, this trick is using python's module doc string to run a mini shell script first.
-
Juan over 5 yearsLinux has
env -S
now, too - as of coreutils 8.30 1 (which may take a while to appear on a distro near you). Same semantics as FreeBSD'senv(1)
- hooray for portability of good features. -
Juan over 5 yearsNote: Most unix-ish #! implementations do not allow scripts to be used for security reasons. I'm surprised this worked on Ubunut 13.10.
-
philwalk over 5 yearsalso works on ubuntu 16.04 as of 2019-01-20, not sure about others.
-
Timmah over 5 yearsNo luck on Solaris (11.3) either... :(
-
dan over 4 yearsDo you need to do this on every restart?
-
artu-hnrq about 3 years@dan: Not while you keep in same shell. After
export
a variable it will keep set until you overwrite orunset
it -
Dariusz Filipiak about 3 years#!/usr/bin/env -S node --inspect - WORKS!