不能传递参数给“#!/ 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
可以工作,但我需要它来获取PATH
的python
来支持虚拟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/env
search一个名为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。 我很确定env
function是普遍的。
我最近为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
放入字段lang
, foo
和--bar
。 它将search解释器lang
PATH
,然后用参数--foo
, bar
,以及脚本的path和脚本的参数调用它。
还有一个function可以在选项中间传递脚本的名称。 假设你想运行lang -f <thecriptname> other-arg
,然后是其余的参数。 有了这个补丁env
,它是这样做的:
#!/usr/bin/env :lang:-f:{}:other-arg
等同于{}
的最左边的字段被replace为后面的第一个参数,在哈希函数调用下,它是脚本名称。 那个论点然后被删除。
在这里, other-arg
可以是由lang
处理的东西,也可以是由脚本处理的东西。
为了更好地理解,请参阅补丁程序中的众多echo
testing用例。
我select了:
字符,因为它是POSIX系统上PATH
使用的现有分隔符。 由于env
执行PATH
search,所以不太可能用于名称包含冒号的程序。 {}
标记来自find
实用程序,它使用它来表示将path插入到-exec
命令行中。