89

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

我发现这是#/usr/bin/python -u可行的,但我需要它pythonPATH支持虚拟env环境。

我有哪些选择?

4

9 回答 9

43

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

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

ps 我们不必担心 sh 的路径,对吧?

于 2012-01-29T07:25:40.520 回答
32

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

对于您的情况:

export PYTHONUNBUFFERED=1
script.py
于 2013-06-06T07:22:58.710 回答
28

这可能有点过时,但 env(1) 手册告诉人们可以在这种情况下使用“-S”

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

它似乎在 FreeBSD 上运行良好。

于 2014-01-29T13:57:24.840 回答
17

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

于 2012-01-19T05:34:29.740 回答
13

将参数传递给 shebang 行不是标准的,并且正如您所试验的那样,它不能与 Linux 中的 env 结合使用。bash 的解决方案是使用内置命令“set”来设置所需的选项。我认为您可以使用 python 命令设置标准输入的无缓冲输出。

my2c

于 2010-07-22T07:16:31.270 回答
8

这是一个替代 的脚本/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 上测试。

于 2014-07-30T20:11:23.507 回答
5

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

#!/bin/bash

python -u <(cat <<"EOF"
# Your script here
print "Hello world"
EOF
)
于 2010-07-22T07:32:10.020 回答
4

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

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

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

于 2015-11-24T20:00:08.760 回答
-2

我最近为 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--barPATHlang--foobar

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

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

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

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

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

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

于 2017-05-26T16:29:22.807 回答