无法使用“#!/usr/bin/env python”将参数传递给 python
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3306518/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Cannot pass an argument to python with "#!/usr/bin/env python"
提问by Eskil
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 with python -u: no such file or directory.
我需要一个直接可执行的 python 脚本,所以我用#!/usr/bin/env python. 但是,我还需要无缓冲输出,所以我尝试了#!/usr/bin/env python -u,但失败了python -u: no such file or directory.
I found out that #/usr/bin/python -uworks, but I need it to get the pythonin PATHto support virtual envenvironments.
我发现#/usr/bin/python -u的作品,但我需要它来获得python在PATH支持虚拟env环境。
What are my options?
我有哪些选择?
采纳答案by Larry Cai
It is better to use environment variable to enable this. See python doc : http://docs.python.org/2/using/cmdline.html
最好使用环境变量来启用此功能。请参阅 python 文档:http: //docs.python.org/2/using/cmdline.html
for your case:
对于您的情况:
export PYTHONUNBUFFERED=1
script.py
回答by neuro
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.
将参数传递给 shebang 行不是标准的,并且正如您所试验的那样,在 Linux 中不能与 env 结合使用。bash 的解决方案是使用内置命令“set”来设置所需的选项。我认为您可以使用 python 命令设置标准输入的无缓冲输出。
my2c
我的2c
回答by imgx64
This is a kludge and requires bash, but it works:
这是一个杂七杂八的东西,需要 bash,但它有效:
#!/bin/bash
python -u <(cat <<"EOF"
# Your script here
print "Hello world"
EOF
)
回答by Jimmy Hartzell
When you use shebang on Linux, the entire rest of the line after the interpreter name is interpreted as a single argument. The python -ugets passed to envas if you'd typed: /usr/bin/env 'python -u'. The /usr/bin/envsearches for a binary called python -u, which there isn't one.
当您在 Linux 上使用 shebang 时,解释器名称之后的整个行将被解释为单个参数。将python -u被传递到env如同您键入:/usr/bin/env 'python -u'。在/usr/bin/env对二进制搜索叫python -u,它没有一个。
回答by Ade YU
In some environment, env doesn't split arguments.
So your env is looking for python -uin your path.
We can use sh to work around.
Replace your shebang with the following code lines and everything will be fine.
在某些环境中, env 不拆分参数。所以你的环境正在python -u你的道路上寻找。我们可以使用 sh 来解决。用以下代码行替换您的shebang,一切都会好起来的。
#!/bin/sh
''''exec python -u -- "#!/usr/bin/env -S python -u
" ${1+"$@"} # '''
# vi: syntax=python
p.s. we need not worry about the path to sh, right?
ps 我们不用担心 sh 的路径,对吧?
回答by user3249132
This might be a little bit outdated but env(1) manual tells one can use '-S' for that case
这可能有点过时,但 env(1) 手册告诉人们可以在这种情况下使用“-S”
#!/bin/bash
ARGS=( ) # separate into multiple space-delimited arguments.
shift # consume
PROG=`which ${ARGS[0]}`
unset ARGS[0] # discard executable name
ARGS+=( "$@" ) # remainder of arguments preserved "as-is".
exec $PROG "${ARGS[@]}"
It seems to work pretty good on FreeBSD.
它似乎在 FreeBSD 上工作得很好。
回答by philwalk
Here is a script alternative to /usr/bin/env, that permits passing of arguments on the hash-bang line, based on /bin/bashand with the restriction that spaces are disallowed in the executable path. I call it "envns" (env No Spaces):
这是一个替代 的脚本/usr/bin/env,它允许在 hash-bang 行上传递参数,基于/bin/bash和限制在可执行路径中不允许使用空格。我称之为“envns”(env No Spaces):
#!/usr/local/bin/envns python -u
Assuming this script is located at /usr/local/bin/envns, here's your shebang line:
假设此脚本位于 /usr/local/bin/envns,这是您的 shebang 行:
#!/usr/bin/env PYTHONUNBUFFERED="YESSSSS" python
Tested on Ubuntu 13.10 and cygwin x64.
在 Ubuntu 13.10 和 cygwin x64 上测试。
回答by Mad Physicist
Building off of Larry Cai's answer, envallows you to set a variable directly in the command line. That means that -ucan be replaced by the equivalent PYTHONUNBUFFEREDsetting before python:
基于 Larry Cai 的回答,env允许您直接在命令行中设置变量。这意味着-u可以用PYTHONUNBUFFERED之前的等效设置替换python:
#!/usr/bin/env :lang:--foo:bar
Works on RHEL 6.5. I am pretty sure that feature of envis just about universal.
适用于 RHEL 6.5。我很确定 的功能几乎env是通用的。
回答by Kaz
I recently wrote a patch for the GNU Coreutils version of envto address this issue:
我最近为 GNU Coreutils 版本编写了一个补丁env来解决这个问题:
http://lists.gnu.org/archive/html/coreutils/2017-05/msg00018.html
http://lists.gnu.org/archive/html/coreutils/2017-05/msg00018.html
If you have this, you can do:
如果你有这个,你可以这样做:
#!/usr/bin/env :lang:-f:{}:other-arg
envwill split :lang:foo:--barinto the fields lang, fooand --bar. It will search PATHfor the interpreter lang, and then invoke it with arguments --foo, bar, plus the path to the script and that script's arguments.
env将拆分:lang:foo:--bar为字段lang,foo和--bar。它将搜索PATH的解释lang,然后用参数调用它--foo,bar加上路径的脚本和脚本的参数。
There is also a feature to pass the name of the script in the middle of the options. Suppose you want to run lang -f <thecriptname> other-arg, followed by the remaining arguments. With this patched env, it is done like this:
还有一个功能可以在选项中间传递脚本的名称。假设您要运行lang -f <thecriptname> other-arg,然后是其余参数。有了这个补丁env,它是这样完成的:
The leftmost field which is equivalent to {}is replaced with the first argument that follows, which, under hash bang invocation, is the script name. That argument is then removed.
最左边的相当于 的字段被后面{}的第一个参数替换,在 hash bang 调用下,它是脚本名称。然后删除该参数。
Here, other-argcould be something processed by langor perhaps something processed by the script.
在这里,other-arg可能是lang由脚本处理的内容,也可能是脚本处理的内容。
To understand better, see the numerous echotest cases in the patch.
为了更好地理解,请参阅echo补丁中的众多测试用例。
I chose the :character because it is an existing separator used in PATHon POSIX systems. Since envdoes PATHsearching, it's vanishingly unlikely to be used for a program whose name contains a colon. The {}marker comes from the findutility, which uses it to denote the insertion of a path into the -execcommand line.
我选择这个:字符是因为它是PATHPOSIX 系统中使用的现有分隔符。由于env做PATH搜索,它是微乎其微不太可能使用其名称中包含冒号的程序。该{}标记来源于find实用程序,它使用它来表示的路径的插入-exec命令行。

