【问题标题】:How to make "#!" portable to different systems which have python installed at different locations?怎么做 ”#!”可移植到在不同位置安装了 python 的不同系统?
【发布时间】:2021-11-07 04:32:18
【问题描述】:

我的脚本在第一行有这个:

#!/usr/bin/python3.6

但是在不同的系统中python3.6安装在不同的位置,比如:

/user/bin/python3.6
/tools/bin/python3.6
/user/local/bin/python3.6

如何使我的脚本在这 3 个系统中表现出色?

【问题讨论】:

  • 为什么这个标签是“bash”? Bash 不参与解析 shebang - 这是由您的操作系统内核完成的。 (严格来说,如果操作系统在 execve() 系统调用或其本地等效项中报告失败,一些 shell 会尝试自己作为后备,但这是操作系统内核的工作;shell 实现,它们何时/何处存在,只是作为操作系统错误的后备/解决方法)。
  • Shebang 并不是为了提供便携性。它们是本地内核关于解释器所在位置的指令。它可以而且应该在安装时适当设置,而不是在编写脚本时给出一个万能的值。
  • @CharlesDuffy 你是对的,但我还是将其重新标记为shell,因为 shebang 行在概念上与 shell 相关联。 shell 将其转发给操作系统(IIRC 通过execve?)这一事实很少有人意识到,并且也不会影响这个问题。
  • @KonradRudolph 也许我们应该强调它不是 shell 自己使用的东西。
  • shell 不转发任何东西;操作系统本身会查看可执行文件的前几个字节以查看其格式。字节#! 被解释为引入用作解释器的路径。 shell 的唯一参与是当操作系统决定它不能执行文件时,shell 可能会尝试其他的东西。 (例如bash,fork 自身以将文件作为bash 脚​​本执行;其他shell 假定应使用默认系统shell。)

标签: python shebang


【解决方案1】:

大致有两种选择:

  1. 不要硬编码路径;而是使用env 来确定路径:

    #!/usr/bin/env python3
    
  2. 或者根本不要编写带有 shebang 行的脚本;相反,使用 setuptools 安装程序创建一个适当的包,并为目标系统设置适当的解释器 instruct setuptools to create an executable file

对于任何不仅仅是快速而肮脏的脚本,或纯粹用于本地使用的脚本,第二种选择更易于维护,并且构成了执行此操作的“正确”方式。

【讨论】:

  • #2 绝对是可取的;您的脚本期望的 Python 版本可能不是用户环境指定的主要 Python 版本。
最近更新 更多