我需要一个可直接执行的python脚本,因此我从开始了该文件#!/usr/bin/env python
。但是,我还需要无缓冲的输出,因此我尝试了#!/usr/bin/env python -u
,但是失败了python -u: no such file or directory
。
我发现#/usr/bin/python -u
的作品,但我需要它来获得python
在PATH
支持虚拟env
环境。
我有什么选择?
Answers:
最好使用环境变量来启用此功能。请参阅python doc:http : //docs.python.org/2/using/cmdline.html
对于您的情况:
export PYTHONUNBUFFERED=1
script.py
在某些环境中,env不会拆分参数。因此,您的环境正在寻找python -u
您的路径。我们可以使用sh解决。将您的shebang替换为以下代码行,一切都会好起来的。
#!/bin/sh
''''exec python -u -- "$0" ${1+"$@"} # '''
# vi: syntax=python
ps我们不必担心sh的路径,对吗?
${1+"$@"}
黑客可能是不必要的:)
"exec" "python" "-u" "--" "$0" "$@"
可能更容易理解-是否存在任何缺陷?(我认为这与1+
黑客行为不兼容吗?)
'
或的字符串"
,那么您的方法将更可靠。这是一个有趣的问题!我的也许更容易理解,但您的却更强大。也许您的答案应该说明它必须以开头''''exec
,并且字符串必须以结尾# '''
(在之前有一个空格#
)。只要我们遵守这些规则,并且没有任何多余的三引号'''
,您的方法就是完美而灵活的。
在Linux上使用shebang时,解释器名称后的其余行将被解释为单个参数。将python -u
被传递到env
如同您键入:/usr/bin/env 'python -u'
。在/usr/bin/env
对二进制搜索叫python -u
,它没有一个。
这是替代脚本的脚本/usr/bin/env
,该脚本基于/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上测试。
这是一个混战,需要重击,但是它可以工作:
#!/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
是通用的。
ps
输出应该没有任何区别),但是它永远不会返回。在Debian中执行此操作时,还不清楚python本身是否真的在运行。我在一些地方尝试过-与同等命令行相比,绝对无法按预期工作。
env
甚至使用的版本有关python
。
我最近为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
,然后运行其余参数。对此进行修补后env
,就可以这样完成:
#!/usr/bin/env :lang:-f:{}:other-arg
等价的最左边的字段被后面{}
的第一个参数替换,在哈希爆炸调用下,该参数是脚本名称。然后删除该参数。
在这里,other-arg
可能是lang
脚本处理过的东西,也可能是脚本处理过的东西。
为了更好地理解,请参阅echo
补丁中的众多测试案例。
我选择该:
字符是因为它是PATH
POSIX系统上使用的现有分隔符。由于env
做PATH
搜索,它是微乎其微不太可能使用其名称中包含冒号的程序。该{}
标记来源于find
实用程序,它使用它来表示的路径的插入-exec
命令行。