无法使用“#!/ usr / bin / env python”将参数传递给python

时间:2010-07-22 07:07:15

标签: python arguments shebang

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

我发现#/usr/bin/python -u有效,但我需要它来python PATH来支持虚拟env环境。

我有什么选择?

9 个答案:

答案 0 :(得分:39)

在某些环境中,env不会拆分参数。 所以你的env正在你的路径中寻找“python -u”。 我们可以用sh来解决。 用以下代码行替换你的shebang,一切都会好的。

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

P.S。我们不用担心sh的路径,对吧?

答案 1 :(得分:21)

最好使用环境变量来启用此功能。请参阅python doc:http://docs.python.org/2/using/cmdline.html

适用于您的情况:

export PYTHONUNBUFFERED=1
script.py

答案 2 :(得分:13)

当您在Linux上使用shebang时,解释器名称后面的整个行的其余部分将被解释为单个参数。 python -u传递给env,就好像您输入了/usr/bin/env 'python -u'一样。 /usr/bin/env搜索名为python -u的二进制文件,但没有一个。{/ p>

答案 3 :(得分:12)

将参数传递给shebang行并不是标准的,因为您已经尝试过,不能与Linux中的env结合使用。使用bash的解决方案是使用内置命令“set”来设置所需的选项。我想你可以用python命令设置无缓冲的stdin输出。

MY2C

答案 4 :(得分:9)

这是/ usr / bin / env的替代脚本,它允许在hash-bang行上传递参数,基于/ bin / bash,并且限制在可执行路径中不允许使用空格。我称之为" 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上测试。

答案 5 :(得分:6)

这可能有点过时,但env(1)手册告诉人可以使用'-S'作为案例

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

它似乎在FreeBSD上运行得很好。

答案 6 :(得分:5)

这是一个kludge,需要bash,但它有效:

#!/bin/bash

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

答案 7 :(得分:4)

根据Larry Cai的回答,env允许您直接在命令行中设置变量。这意味着-u可以替换为PYTHONUNBUFFERED之前的等效python设置:

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

适用于RHEL 6.5。我很确定env的功能几乎是普遍的。

答案 8 :(得分:-1)

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

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

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

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

env会将:lang:foo:--bar分为langfoo--bar字段。它将在PATH中搜索解释器lang,然后使用参数--foobar,以及脚本的路径和脚本的参数来调用它。

还有一个功能可以在选项中间传递脚本的名称。假设您要运行lang -f <thecriptname> other-arg,然后运行其余参数。使用此修补后的env,可以这样完成:

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

相当于{}的最左边的字段被替换为后面的第一个参数,在hash bang调用下,它是脚本名称。然后删除该论点。

此处,other-arg可能是lang处理的内容,也可能是脚本处理的内容。

为了更好地理解,请参阅补丁中的众多echo测试用例。

我选择了:字符,因为它是POSIX系统上PATH中使用的现有分隔符。由于env进行PATH搜索,因此它不太可能用于名称中包含冒号的程序。 {}标记来自find实用程序,该实用程序使用它来表示将路径插入-exec命令行。