我需要有一个直接可执行的 python 脚本,所以我用#!/usr/bin/env python
. 但是,我也需要无缓冲的输出,所以我尝试#!/usr/bin/env python -u
了,但失败了python -u: no such file or directory
。
我发现这是#/usr/bin/python -u
可行的,但我需要它python
来PATH
支持虚拟env
环境。
我有哪些选择?
在某些环境中, env 不会拆分参数。python -u
所以你的环境正在你的路径中寻找。我们可以使用 sh 来解决。用以下代码行替换您的 shebang,一切都会好起来的。
#!/bin/sh
''''exec python -u -- "$0" ${1+"$@"} # '''
# vi: syntax=python
ps 我们不必担心 sh 的路径,对吧?
最好使用环境变量来启用它。请参阅 python 文档:http ://docs.python.org/2/using/cmdline.html
对于您的情况:
export PYTHONUNBUFFERED=1
script.py
这可能有点过时,但 env(1) 手册告诉人们可以在这种情况下使用“-S”
#!/usr/bin/env -S python -u
它似乎在 FreeBSD 上运行良好。
当您在 Linux 上使用 shebang 时,解释器名称之后的整个其余行都被解释为单个参数。被python -u
传递给env
就好像你输入了: /usr/bin/env 'python -u'
。/usr/bin/env
搜索名为 的二进制文件,python -u
但没有。
将参数传递给 shebang 行不是标准的,并且正如您所试验的那样,它不能与 Linux 中的 env 结合使用。bash 的解决方案是使用内置命令“set”来设置所需的选项。我认为您可以使用 python 命令设置标准输入的无缓冲输出。
my2c
这是一个替代 的脚本/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 上测试。
这是一个 kludge 并且需要 bash,但它有效:
#!/bin/bash
python -u <(cat <<"EOF"
# Your script here
print "Hello world"
EOF
)
根据 Larry Cai 的回答,env
您可以直接在命令行中设置变量。这意味着-u
可以用PYTHONUNBUFFERED
之前的等效设置替换python
:
#!/usr/bin/env PYTHONUNBUFFERED="YESSSSS" python
适用于 RHEL 6.5。我很确定该功能几乎env
是通用的。
我最近为 GNU Coreutils 版本编写了一个补丁env
来解决这个问题:
http://lists.gnu.org/archive/html/coreutils/2017-05/msg00018.html
如果你有这个,你可以这样做:
#!/usr/bin/env :lang:--foo:bar
env
将拆分为:lang:foo:--bar
字段lang
和。它将搜索解释器,然后使用参数调用它,加上脚本的路径和该脚本的参数。foo
--bar
PATH
lang
--foo
bar
还有一个功能可以在选项中间传递脚本的名称。假设您要运行lang -f <thecriptname> other-arg
,然后是剩余的参数。有了这个 patched env
,它是这样完成的:
#!/usr/bin/env :lang:-f:{}:other-arg
最左边的字段{}
被替换为后面的第一个参数,在 hash bang 调用下,它是脚本名称。然后删除该参数。
在这里,other-arg
可能是脚本处理的东西,也lang
可能是脚本处理的东西。
为了更好地理解,请查看补丁中的众多echo
测试用例。
我选择了这个字符,因为它是POSIX 系统:
中使用的现有分隔符。PATH
由于搜索,env
它PATH
几乎不可能用于名称包含冒号的程序。该{}
标记来自find
实用程序,该实用程序使用它来表示将路径插入-exec
命令行。