Краткая история: Строка shebang (#!
) читается оболочкой (например, sh
, bash
и т. Д.) загрузчиком программы операционной системы.Хотя это формально выглядит как комментарий, тот факт, что это первые два байта файла, отмечает весь файл как текстовый файл и как скрипт.Скрипт будет передан исполняемому файлу, указанному в первой строке после шебанга.Вуаля!
Немного более длинная история: Представьте, что у вас есть скрипт, foo.sh
, с установленным исполняемым битом (x
).Этот файл содержит, например, следующее:
#!/bin/sh
# some script commands follow...:
# *snip*
Теперь на вашей оболочке вы набираете:
> ./foo.sh
Редактировать: Пожалуйста, такжеПрочитайте комментарии ниже после или до того, как прочитаете следующее!Как оказалось, я ошибся.Очевидно, что не оболочка передает скрипт целевому интерпретатору, а сама операционная система (ядро).
Помните, что вы вводите это внутри процесса оболочки (предположим, что этопрограмма /bin/sh
).Поэтому этот ввод должен быть обработан этой программой.Он интерпретирует эту строку как команду, поскольку обнаруживает, что самое первое, что вводится в строку, - это имя файла, который фактически существует и в котором установлены исполняемые биты.
/bin/sh
затемначинает чтение содержимого файла и обнаруживает шебанг (#!
) в самом начале файла.Для оболочки это токен («магическое число»), по которому он знает, что файл содержит скрипт.
Теперь, как он узнает, на каком языке программирования написан скрипт?В конце концов, вы можете выполнять скрипты Bash, Perl, Python ... Все, что знает оболочка, это то, что она просматривает файл скрипта (который является не двоичным, а текстовым файлом).Таким образом, он читает следующий ввод до первого разрыва строки (что приведет к /bin/sh
, сравните с вышеупомянутым).Это интерпретатор, которому скрипт будет передан для исполнения.(В данном конкретном случае целевой интерпретатор является самой оболочкой, поэтому ему не нужно вызывать новую оболочку для сценария; он просто обрабатывает остальную часть самого файла сценария.)
Если сценарийпредназначено, например, для /bin/perl
, все, что интерпретатор Perl должен (необязательно) должен сделать, это посмотреть, действительно ли в строке shebang упоминается интерпретатор Perl.Если нет, интерпретатор Perl будет знать, что он не может выполнить этот скрипт.Если действительно интерпретатор Perl упоминается в строке shebang, он читает остальную часть файла сценария и выполняет его.