Как делает #! работа хижины?

В сценарии необходимо включать a #! на первой строке, сопровождаемой путем к программе, которая выполнит сценарий (например: sh, жемчуг).

Насколько я знаю, # символ обозначает запуск комментария, и та строка, как предполагается, проигнорирована программой, выполняющей сценарий. Это казалось бы, что эта первая строка в какой-то момент читается чем-то для сценария, который будет выполняться надлежащей программой.

Мог кто-то проливать больше света на работы #!?

Мне действительно любопытно на предмет этого, таким образом, чем более всесторонний ответ, тем лучше.

43
задан Jonathan Leffler 11 September 2014 в 18:38
поделиться

2 ответа

Рекомендуемая литература:

За это отвечает загрузчик программ ядра unix. Когда вызывается exec () , он просит ядро ​​загрузить программу из файла по своему аргументу. Затем он проверит первые 16 бит файла, чтобы узнать, какой у него исполняемый формат. Если он обнаружит, что это #! он будет использовать оставшуюся часть первой строки файла, чтобы определить, какую программу он должен запустить, и предоставит имя файла, который он пытался запустить (сценарий), в качестве последнего аргумента программы интерпретатора.

Затем интерпретатор работает в обычном режиме и обрабатывает #! в качестве комментария.

42
ответ дан 26 November 2019 в 23:02
поделиться

Краткая история: Строка shebang (#!) читаетсяоболочкой (например, sh, bash и т.д.) загрузчика программ операционной системы. Хотя формально это выглядит как комментарий, тот факт, что это самые первые два байта файла, маркирует весь файл как текстовый файл и как сценарий. Сценарий будет передан исполняемому файлу, упомянутому в первой строке после shebang. Вуаля!


Немного более длинная история: Представьте, что у вас есть сценарий foo.sh с установленным исполняемым битом (x). Этот файл содержит, например, следующее:

#!/bin/sh

# some script commands follow...:
# *snip*

Теперь в оболочке вы набираете:

> ./foo.sh

Edit: Пожалуйста, прочитайте также комментарии ниже после или до того, как вы прочитаете следующее! Как оказалось, я ошибался. Очевидно, что не оболочка передает сценарий целевому интерпретатору, а сама операционная система (ядро).

Помните, что вы набираете это внутри процесса shell (предположим, что это программа /bin/sh). Поэтому этот ввод должен быть обработан этой программой. Она интерпретирует эту строку как команду, поскольку обнаруживает, что первое, что введено в строке, - это имя файла, который действительно существует и у которого установлен исполняемый бит(ы).

/bin/sh затем начинает читать содержимое файла и обнаруживает шебанг (#!) в самом начале файла. Для shell это маркер ("магическое число"), по которому он узнает, что файл содержит сценарий.

Теперь, как он узнает, на каком языке программирования написан сценарий? В конце концов, вы можете выполнять сценарии Bash, Perl, Python... Все, что shell пока знает, это то, что он смотрит на файл сценария (который является не двоичным, а текстовым файлом). Таким образом, он читает следующий ввод до первого перевода строки (что приведет к /bin/sh, сравните с приведенным выше). Это интерпретатор, которому будет передан сценарий для выполнения. (В данном конкретном случае целевым интерпретатором является сам shell, поэтому ему не нужно вызывать новый shell для скрипта; он просто сам обрабатывает остальную часть файла скрипта).

Если бы скрипт предназначался, например, для /bin/perl, все, что интерпретатору Perl (по желанию) нужно было бы сделать, это посмотреть, действительно ли в строке shebang упоминается интерпретатор Perl. Если нет, то интерпретатор Perl будет знать, что он не может выполнить этот сценарий. Если интерпретатор Perl действительно упоминается в строке shebang, он прочитает остальную часть файла сценария и выполнит его.

9
ответ дан 26 November 2019 в 23:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: