Почему этот фрагмент кода с shebang #!/ Bin/sh и exec python внутри 4 одинарных кавычек работает?

Я пытаюсь понять один из ответов на этот вопрос:

Невозможно передать аргумент python с помощью "#!/ Usr/bin/env python"

#!/bin/sh
''''exec python -u -- "$0" ${1+"$@"} # '''

Это хорошо работает, но я не понимаю, почему это работает с четырьмя тиками в начале этой строки, а не с тремя.

Кроме того, почему хэш в конце этой строки?

2 ответа

Решение

Python поддерживает строки в тройных кавычках:

'''something'''

Оболочка поддерживает только строки в одинарных кавычках:

'something'

Используя четыре цитаты, sh видит это как 2 пустых строки, но Python видит первые три как начало строки в тройных кавычках и включает четвертую часть как строковое значение.

Остальная часть строки затем интерпретируется как команда sh, но как часть строки Python.

# затем формирует комментарий, насколько sh обеспокоен, но это все еще строка для Python, закрывающая его тройной кавычкой.

Итак, подведем итог:

  • sh видит: пустая строка ( '' ) - пустая строка ( '' ) - команда ( exec python -u -- "$0" ${1+"$@"} ) - комментарий ( # ''' )
  • Python видит: строковый литерал с тройными кавычками (содержащий символы 'exec python -u -- "$0" ${1+"$@"} # )

Так sh выполняет эту команду, заменяя себя python -u -- с именем сценария и остальными аргументами командной строки, и Python читает этот файл и просто видит начальный строковый литерал, который никуда не денется.

Поскольку это первый строковый литерал в файле, он будет установлен как строка документации для __main__ модуль, но это вряд ли будет иметь значение, если это основной сценарий.

Я просто использую:

#!/bin/sh
''':'
exec python -tt "$0" "$@"
'''
# The above shell shabang trick is more portable than /usr/bin/env and supports adding arguments to the interpreter (python -tt)
Другие вопросы по тегам