无法使用“#!/usr/bin/env python”将参数传递给 python
- 2025-03-14 08:57:00
- admin 原创
- 59
问题描述:
我需要一个可直接执行的 Python 脚本,因此我用 启动了文件#!/usr/bin/env python
。但是,我还需要无缓冲输出,因此我尝试了#!/usr/bin/env python -u
,但使用 失败了python -u: no such file or directory
。
我发现它#/usr/bin/python -u
是有效的,但我需要它来python
支持PATH
虚拟env
环境。
我有什么选择?
解决方案 1:
在某些环境中,env 不会拆分参数。因此您的 env 正在python -u
您的路径中查找。我们可以使用 sh 来解决。用以下代码行替换您的 shebang,一切都会好起来。
#!/bin/sh
''''exec python -u -- "$0" ${1+"$@"} # '''
# vi: syntax=python
ps 我们不必担心 sh 的路径,对吗?
解决方案 2:
这可能有点过时,但 env(1) 手册告诉我们,在这种情况下可以使用 '-S'
#!/usr/bin/env -S python -u
它在 FreeBSD 上似乎运行得很好。
解决方案 3:
最好使用环境变量来启用此功能。请参阅 python 文档:http://docs.python.org/2/using/cmdline.html
针对你的情况:
export PYTHONUNBUFFERED=1
script.py
解决方案 4:
当您在 Linux 上使用 shebang 时,解释器名称后面的整行其余部分将被解释为单个参数。 传递python -u
给 ,env
就像您输入了:一样/usr/bin/env 'python -u'
。/usr/bin/env
搜索名为 的二进制文件python -u
,但不存在。
解决方案 5:
将参数传递给 shebang 行不是标准的,并且正如您所试验的那样,在 Linux 中与 env 结合使用时不起作用。bash 的解决方案是使用内置命令“set”来设置所需的选项。我认为您可以做同样的事情来使用 python 命令设置 stdin 的无缓冲输出。
我的
解决方案 6:
以下是 的替代脚本/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 上测试。
解决方案 7:
这是一个临时解决方案,需要 bash,但它可以工作:
#!/bin/bash
python -u <(cat <<"EOF"
# Your script here
print "Hello world"
EOF
)
解决方案 8:
基于 Larry Cai 的回答,env
您可以直接在命令行中设置变量。这意味着可以用之前的-u
等效设置替换:PYTHONUNBUFFERED
`python`
#!/usr/bin/env PYTHONUNBUFFERED="YESSSSS" python
适用于 RHEL 6.5。我确信该功能env
几乎是通用的。
解决方案 9:
我最近为 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
为了更好地理解,请参阅补丁中的大量测试用例。
我之所以选择该字符,是因为它是POSIX 系统:
中使用的现有分隔符。由于它用于搜索,因此它不太可能用于名称包含冒号的程序。该标记来自实用程序,它使用它来表示将路径插入命令行。PATH
`envPATH
{}find
-exec`
扫码咨询,免费领取项目管理大礼包!