![如何在我的 shebang 中使用环境变量?](https://linux22.com/image/17985/%E5%A6%82%E4%BD%95%E5%9C%A8%E6%88%91%E7%9A%84%20shebang%20%E4%B8%AD%E4%BD%BF%E7%94%A8%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F%EF%BC%9F.png)
我有一个 Python 脚本,需要与特定的 python 安装一起运行。有没有办法制作一个 shebang 以便它与 一起运行$FOO/bar/MyCustomPython
?
答案1
shebang 线非常有限。在许多 UNIX 变体(包括 Linux)下,只能有两个单词:一个命令和一个参数。通常还存在长度限制。
一般的解决方案是编写一个小的 shell 包装器。为Python 脚本命名foo.py
,然后将shell 脚本放在旁边foo.py
并调用它foo
。此方法不需要 Python 脚本上的任何特定标头。
#!/bin/sh
exec "$FOO/bar/MyCustomPython" "$0.py" "$@"
另一种诱人的方法是编写一个像上面那样的包装脚本,并将其#!/path/to/wrapper/script
作为 shebang 行放在 Python 脚本上。然而,大多数 unice 不支持 shebang 脚本的链接,因此这不起作用。
如果MyCustomPython
在 中$PATH
,您可以使用env
以下方式查找:
#!/usr/bin/env MyCustomPython
import …
另一种方法是将脚本安排为既有效的 shell 脚本(其自身加载正确的 Python 解释器)又是目标语言(此处为 Python)的有效脚本。这需要您找到一种方法来为您的目标语言编写这样的双语言脚本。在 Perl 中,这被称为if $running_under_some_shell
。
#!/bin/sh
eval 'exec "$FOO/bar/MyCustomPerl" -wS $0 ${1+"$@"}'
if $running_under_some_shell;
use …
这是在 Python 中实现相同效果的一种方法。在 shell 中,"true"
是true
实用程序,它忽略其参数(两个单字符字符串:
和'
)并返回 true 值。在 Python 中,"true"
是一个字符串,当解释为布尔值时为 true,因此这是一条if
始终为 true 并执行字符串文字的指令。
#!/bin/sh
if "true" : '''\'
then
exec "$FOO/bar/MyCustomPython" "$0" "$@"
exit 127
fi
'''
import …
答案2
Shebang 行不会进行变量扩展,因此您不能使用它,$FOO/MyCustomPython
因为它会搜索名为 Dollar-FOO-... 的可执行文件。
另一种方法是让 shebang 指向 shell 脚本作为解释器,然后该 shell 脚本可以使用环境变量来找到正确的脚本并执行它。
示例:在(或您的 上的任何其他目录)中创建一个mypython.sh
脚本,包含以下内容:/usr/local/bin
$PATH
#! /bin/sh
PYTHON="$FOO/bar/MyCustomPython"
exec "$PYTHON" "$@"
MyCustomPython
那么你可以使用这个 shebang 行通过via执行 Python 脚本mypython.sh
:
#!/usr/bin/env mypython.sh
答案3
您可以使用自定义 python 安装的绝对路径,也可以将其放入您的$PATH
并使用#!/usr/bin/env [command]
.否则,为其编写一个包装器并用于exec
替换过程映像,例如:
#!/bin/bash
exec "$ENV/python" "$@"
答案4
如果您可以将$FOO
in替换$FOO/bar/MyCustomPython
为具体路径选项,则可以通过直接在其中env
设置自定义来告诉 shebang 行在哪里查找您的自定义 Python 版本。PATH
#!/usr/bin/env PATH="/path1/to/MyCustomPython:/path2/to/MyCustomPython" python
编辑:似乎只有在 PATH 值分配周围没有引号的情况下才有效:
#!/usr/bin/env PATH=/path1/to/MyCustomPython:/path2/to/MyCustomPython python