为什么这个shell脚本以python脚本的形式调用自己?

12 投票
1 回答
706 浏览
提问于 2025-04-16 15:12

显然,这个 shell 脚本是以 Python 脚本的方式在调用自己:

#!/bin/sh
## repo default configuration
##
REPO_URL='git://android.git.kernel.org/tools/repo.git'
REPO_REV='stable'

magic='--calling-python-from-/bin/sh--'
"""exec" python -E "$0" "$@" """#$magic"
if __name__ == '__main__':
  import sys
  if sys.argv[-1] == '#%s' % magic:
    del sys.argv[-1]
del magic
:
:

(完整脚本:https://android.googlesource.com/tools/repo/+/v1.0/repo

有没有人能解释一下:

  • 这样调用的目的是什么?
    为什么不在第一行加上 #!/usr/bin/env python,这样一开始就能被当作 Python 脚本来解释呢?

  • 添加那个神秘的最后一个命令行参数的目的是什么?这个参数在 Python 代码开始时又被去掉了?

1 个回答

8

你的第一个问题:这样做是为了修复一些Unix系统(或者模拟Unix的系统),因为它们对#!这个符号的处理不正确或者根本不处理。这里的技巧在于,写一个脚本既能在shell中正确运行,也能在其他语言中正常工作。以perl为例,我们常常会看到类似这样的写法:

exec "/usr/bin/perl"
   if 0;

这里的exec是由shell来解释和执行的,但perl解释器看到的是一个条件语句(.... if ...),因为条件不成立,所以它什么也不做。

撰写回答