为什么这个shell脚本以python脚本的形式调用自己?
显然,这个 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 ...),因为条件不成立,所以它什么也不做。