Почему этот сценарий оболочки вызывает себя как скрипт python?

#android #python #sh

#Android #python #sh

Вопрос:

Очевидно, что этот скрипт оболочки вызывает себя как скрипт 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. По-моему, пахнет бюрократией.

2. @Will: Вы имеете в виду, что у автора было какое-то нетехническое ограничение, которое допускает только сценарии оболочки, без сценариев Python; поэтому он написал скрипт Python, который формально является сценарием оболочки?

3. Думаю, мне нужно поработать над своим сухим чувством юмора. Ответ Инго — наиболее вероятная реальная причина.

Ответ №1:

Ваш первый вопрос: это сделано для исправления систем unix (или их эмуляций), которые неправильно или вообще не обрабатывают #!. Высокое искусство состоит в том, чтобы создать скрипт, который корректен как в shell, так и на другом языке. Для perl часто можно увидеть что-то вроде:

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

Exec интерпретируется и выполняется оболочкой, но интерпретатор perl видит условный оператор (…. if …) и ничего не делает, потому что условие равно false.

Комментарии:

1. Также может использоваться в системах, которые корректно обрабатывают #!, но явно используют sh для интерпретации сценариев в определенном каталоге.

2. Или даже для обработки систем, которые определенно не имеют /usr/bin/env .