不能传递参数给“#!/ usr / bin / env python”

我需要一个直接可执行的Python脚本,所以我用#!/usr/bin/env python启动了这个文件。 然而,我也需要无缓冲的输出,所以我试过#!/usr/bin/env python -u ,但是这个失败了, python -u: no such file or directory

我发现#/usr/bin/python -u可以工作,但我需要它来获取PATHpython来支持虚拟env环境。

我有什么select?

最好使用环境variables来启用它。 请参阅python文档: http : //docs.python.org/2/using/cmdline.html

为你的情况:

 export PYTHONUNBUFFERED=1 script.py 

在某些环境中,env不会分割参数。 所以你的env在你的path上寻找“python -u”。 我们可以用sh来解决。 用下面的代码行replace你的shebang,一切都会好起来的。

 #!/bin/sh ''''exec python -u -- "$0" ${1+"$@"} # ''' # vi: syntax=python 

ps我们不用担心sh的path,对吧?

将parameter passing给shebang行并不是标准的,因为你已经试验过,在Linux中不能和env结合使用。 使用bash的解决scheme是使用内置命令“set”来设置所需的选项。 我想你也可以用python命令设置stdin的无缓冲输出。

MY2C

当您在Linux上使用shebang时,解释器名称后面的整行内容将被解释为单个参数。 python -u被传递给env ,就好像你input了: /usr/bin/env 'python -u'/usr/bin/envsearch一个名为python -u的二进制文件,但没有一个。

这是一个替代/ usr / bin / env的脚本,它允许基于/ bin / bash和在可执行文件path中不允许空格的限制传递散列行上的参数。 我称之为“envns”(env No Spaces):

 #!/bin/bash ARGS=( $1 ) # separate $1 into multiple space-delimited arguments. shift # consume $1 PROG=`which ${ARGS[0]}` unset ARGS[0] # discard executable name ARGS+=( "$@" ) # remainder of arguments preserved "as-is". exec $PROG "${ARGS[@]}" 

假设这个脚本位于/ usr / local / bin / envns,这里是你的shebang行:

 #!/usr/local/bin/envns python -u 

在Ubuntu 13.10和cygwin x64上进行testing。

这可能有些过时,但env(1)手册告诉我们可以使用'-S'作为这种情况

 #!/usr/bin/env -S python -u 

在FreeBSD上它似乎工作得很好。

这是一个kludge,需要bash,但它的作品:

 #!/bin/bash python -u <(cat <<"EOF" # Your script here print "Hello world" EOF ) 

根据Larry Cai的回答, env允许你直接在命令行设置一个variables。 这意味着-u可以被python之前的等价的PYTHONUNBUFFERED设置replace:

 #!/usr/bin/env PYTHONUNBUFFERED="YESSSSS" python 

适用于RHEL 6.5。 我很确定envfunction是普遍的。

我最近为GNU Coreutils版本的env写了一个补丁来解决这个问题:

http://lists.gnu.org/archive/html/coreutils/2017-05/msg00018.html

如果你有这个,你可以这样做:

 #!/usr/bin/env :lang:--foo:bar 

env将split :lang:foo:--bar放入字段langfoo--bar 。 它将search解释器lang PATH ,然后用参数--foobar ,以及脚本的path和脚本的参数调用它。

还有一个function可以在选项中间传递脚本的名称。 假设你想运行lang -f <thecriptname> other-arg ,然后是其余的参数。 有了这个补丁env ,它是这样做的:

 #!/usr/bin/env :lang:-f:{}:other-arg 

等同于{}的最左边的字段被replace为后面的第一个参数,在哈希函数调用下,它是脚本名称。 那个论点然后被删除。

在这里, other-arg可以是由lang处理的东西,也可以是由脚本处理的东西。

为了更好地理解,请参阅补丁程序中的众多echotesting用例。

我select了:字符,因为它是POSIX系统上PATH使用的现有分隔符。 由于env执行PATHsearch,所以不太可能用于名称包含冒号的程序。 {}标记来自find实用程序,它使用它来表示将path插入到-exec命令行中。