【问题标题】:why does "#!/usr/bin/env PATH=... python" hang, and how else can you specify a PATH when invoking python?为什么“#!/usr/bin/env PATH=... python”会挂起,在调用 python 时如何指定 PATH?
【发布时间】:2020-12-12 07:04:18
【问题描述】:

(为了answer it提出问题,起初对此感到困惑。显然欢迎其他答案。)

使用#!/usr/bin/env python 是一个常见的技巧,它允许使用PATH 查找找到python 解释器,而不是硬编码python 的路径。调整它以将 PATH=... 参数添加到 env 可能会很方便,以便硬编码候选目录列表,而不是硬编码单个确切路径。 (这将利用env 在定位python 时使用指定的PATH 变量这一事实,除了将其传递给python 进程。)

例如(test.py):

#!/usr/bin/env PATH=/opt/python/bin:/usr/bin:/bin python

import sys
print(sys.executable)  # show which executable it found

但是如果你尝试这个,虽然如果从 shell 命令行显式执行该命令会起作用:

$ echo $PATH
/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

$ /usr/bin/env PATH=/opt/python/bin:/usr/bin:/bin python ./test.py
/opt/python/bin/python

尝试通过 shebang 运行时失败:

$ ./test.py
[hangs - infinite loop]

为什么会这样,可以做些什么呢?

【问题讨论】:

    标签: python linux command-line-arguments shebang


    【解决方案1】:

    关于失败的原因,原来这是here描述的问题的一个例子。

    至于可以做些什么,可以调整各种this workaround来解决类似的问题,即如何在#!/usr/bin/env python中将参数传递给python(虽然不是完全相同的问题,也与希望在 shebang 行中包含两个以上的项目有关)。

    这给出了:

    #!/bin/sh
    ''''export PATH=/opt/python/bin:/usr/bin:/bin; exec python "$0" # '''
    
    import sys
    print(sys.executable)
    

    通过shebang调用它,我们得到:

    $ ./test.py 
    /opt/python/bin/python
    

    涉及#!/usr/bin/env -S PATH=... python (GNU coreutils >= 8.30) 的解决方案似乎仍然不够便携(例如 Ubuntu 18.04.4,它是 2020 年 4 月之前的最新 LTS 版本,具有 coreutils 8.28)。

    【讨论】:

      最近更新 更多