Shebang (Unix)

редактировать

В вычислениях shebang - это последовательность символов, состоящая из символов числовой знак и восклицательный знак (#!) В начале скрипта. Это также называется sha-bang, hashbang, pound-bang или hash-pling .

. Когда текстовый файл с shebang используется, как если бы это исполняемый файл в Unix-подобной операционной системе, механизм загрузчика программ анализирует остальную часть начальной строки файла как директиву интерпретатора . Загрузчик выполняет указанную программу интерпретатора , передавая ей в качестве аргумента путь, который изначально использовался при попытке запустить скрипт, чтобы программа могла использовать файл в качестве входных данных. Например, если сценарий назван по пути path / to / script и начинается со следующей строки, #! / Bin / sh, то загрузчик программы получает указание запустить программу / bin / sh, передав путь / к / скрипту в качестве первого аргумента. В Linux такое поведение является результатом кода ядра и пользовательского пространства.

Строка shebang обычно игнорируется интерпретатором, поскольку символ «#» - это комментарий маркер во многих скриптовых языках; некоторые языковые интерпретаторы, которые не используют знак решетки для начала комментариев, все же могут игнорировать строку shebang, осознавая ее назначение.

Содержание
  • 1 Синтаксис
  • 2 Примеры
  • 3 Цель
    • 3.1 Сильные стороны
  • 4 Переносимость
    • 4.1 Расположение программы
    • 4.2 Интерпретация символов
    • 4.3 Магическое число
  • 5 Этимология
  • 6 История
  • 7 См. Также
  • 8 Ссылки
  • 9 Внешние ссылки
Синтаксис

Директива интерпретатора shebang имеет следующую форму:

#! Интерпретатор [optional-arg]

в котором интерпретатор абсолютный путь к исполняемой программе.

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

В Linux файл, указанный интерпретатором, может быть выполнен, если он имеет право на выполнение и содержит код, который ядро ​​может выполнить напрямую, если для него определена оболочка через sysctl ( например, для выполнения двоичных файлов Microsoft .exe с использованием wine ), или если он содержит shebang. В Linux и Minix интерпретатор также может быть скриптом. Цепочка shebangs и оберток дает непосредственно исполняемый файл, который получает встречающиеся скрипты в качестве параметров в обратном порядке. Например, если файл / bin / A является исполняемым файлом в формате ELF, файл / bin / B содержит параметр shebang #! / Bin / A optparam, а файл / bin / C содержит параметр shebang #! / bin / B, затем выполнение файла / bin / C преобразуется в / bin / B / bin / C, который, наконец, преобразуется в / bin / A optparam / bin / B / bin / C.

В операционных системах, производных от Solaris и Darwin (таких как macOS ), файл, указанный интерпретатором, должен быть исполняемым двоичным файлом и сам не может быть сценарий.

Примеры

Некоторые типичные строки shebang:

  • #! / bin / sh- Выполнить файл с помощью оболочки Bourne или совместимая оболочка, предполагается, что она находится в каталоге / bin
  • #! / bin / bash- Выполнить файл с помощью оболочки Bash
  • #! / usr / bin / env python3- Выполнить с помощью интерпретатора Python, используя путь поиска программы, чтобы найти его
  • #! / Bin / false- ничего не делать, но возвращать ненулевое состояние выхода, что указывает на сбой. Используется для предотвращения автономного выполнения файла сценария, предназначенного для выполнения в определенном контексте, например командой .из sh / bash, sourceиз csh / tcsh или как.profile,.cshrc или файл.login.

Строки Shebang могут включать определенные параметры, которые передаются интерпретатору. Однако реализации различаются поведением синтаксического анализа параметров; для переносимости следует указать только один параметр без каких-либо пробелов. Дополнительные инструкции по переносимости приведены ниже.

Назначение

Директивы интерпретатора позволяют использовать сценарии и файлы данных в качестве команд, скрывая детали их реализации от пользователей и других программ, устраняя необходимость в префиксе сценариев с их интерпретатором на командная строка.

A сценарий оболочки Борна, который определяется путем some / path / to / foo, имеет начальную строку,

#! / Bin / sh -x

и выполняется с параметрами bar и baz как

some / path / to / foo bar baz

дает результат, аналогичный фактическому выполнению вместо этого следующей командной строки:

/ bin / sh -x some / path / to / foo bar baz

Если / bin / sh указывает оболочку Bourne, то конечным результатом будет то, что все команды оболочки в файле / path / to / foo выполняются с позиционными переменными $ 1 и $ 2, имеющими значения bar и baz соответственно. Кроме того, поскольку начальный числовой знак - это символ, используемый для введения комментариев в языке Bourne shell (и в языках, понятных многим другим интерпретаторам), вся строка shebang игнорируется переводчик.

Однако интерпретатор должен игнорировать строку shebang; таким образом, сценарий, состоящий из следующих двух строк, просто отображает обе строки в стандартный вывод при запуске:

#! / bin / cat Hello world!

Сильные стороны

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

Переносимость

Расположение программы

Shebangs должны указывать абсолютные пути (или пути относительно текущего рабочего каталога) к системным исполняемым файлам; это может вызвать проблемы в системах с нестандартной структурой файловой системы. Даже когда в системах используются довольно стандартные пути, вполне возможно, что варианты одной и той же операционной системы имеют разные местоположения для нужного интерпретатора. Python, например, может находиться в / usr / bin / python3, / usr / local / bin / python3 или даже что-то вроде / home / username / bin / python3, если он установлен обычным пользователем.

Аналогичная проблема существует для оболочки POSIX, поскольку POSIX только требовал, чтобы ее имя было sh, но не указывал путь. Обычное значение - / bin / sh, но некоторые системы, такие как Solaris, имеют POSIX-совместимую оболочку в / usr / xpg4 / bin / sh. Во многих системах Linux / bin / sh - это жесткая или символическая ссылка на / bin / bash, оболочку Bourne Again (BASH). Использование специфического для bash синтаксиса при сохранении shebang, указывающего на sh, также не переносимо.

Из-за этого иногда требуется отредактировать строку shebang после копирования script с одного компьютера на другой. потому что путь, который был закодирован в сценарии, может не применяться на новой машине, в зависимости от согласованности в прошлом соглашении о размещении интерпретатора. По этой причине и поскольку POSIX не стандартизирует имена путей, POSIX не стандартизирует эту функцию.

Часто для обхода этого ограничения можно использовать программу / usr / bin / env, введя уровень косвенный адрес. #!, за которым следует / usr / bin / env, за которым следует желаемая команда без полного пути, как в этом примере:

#! / usr / bin / env sh

В основном это работает, потому что путь / usr / bin / env обычно используется для утилиты env, и она вызывает первый sh, найденный в $ PATH пользователя, обычно / bin / sh.

У этого все еще есть некоторые проблемы с переносимостью с OpenServer 5.0.6 и Unicos 9.0.2, у которых есть только / bin / env и нет / usr / bin / env.

Интерпретация символов

Другой проблемой переносимости является интерпретация аргументов команды. Некоторые системы, включая Linux, не разделяют аргументы; например, при запуске сценария с первой строкой вида

#! / usr / bin / env python3 -c

То есть, python3 -cбудет передается как один аргумент в / usr / bin / env, а не как два аргумента. Cygwin тоже ведет себя подобным образом.

Сложные вызовы интерпретатора возможны за счет использования дополнительной оболочки. FreeBSD 6.0 (2005) представила параметр -S для своего окружения, поскольку он изменил поведение чтения shebang на неразрывное. Эта опция указывает env разделить саму строку. Утилита GNU env, начиная с coreutil 8.30 (2018), также включает эту функцию. Хотя использование этой опции уменьшает проблему переносимости на стороне ядра с разделением, она добавляет требование, чтобы env поддерживал это конкретное расширение.

Другой проблемой являются сценарии, содержащие символ возврата каретки сразу после строки shebang, возможно, в результате редактирования в системе, которая использует DOS разрывы строк, например как Microsoft Windows. Некоторые системы интерпретируют символ возврата каретки как часть команды интерпретатора , что приводит к сообщению об ошибке.

Магическое число

Shebang на самом деле является понятным для человека экземпляром магическое число в исполняемом файле, строка магических байтов 0x23 0x21, двухсимвольная кодировка в ASCII из # !. Это магическое число обнаруживается семейством функций «exec », которые определяют, является ли файл сценарием или исполняемым двоичным файлом. Наличие shebang приведет к выполнению указанного исполняемого файла, обычно интерпретатора языка сценария. Утверждалось, что некоторые старые версии Unix ожидают, что за обычным шебангом следует пробел и косая черта (#! /), но это, похоже, неверно; скорее, пробелы после shebang традиционно допускаются и иногда документируются с пробелом (см. электронное письмо 1980 г. в разделе history ниже).

Символы shebang представлены теми же двумя байтами в расширенных кодировках ASCII, включая UTF-8, который обычно используется для скриптов и других текстовых файлов в настоящее время. Unix-подобные системы. Однако файлы UTF-8 могут начинаться с необязательной метки порядка байтов (BOM); если функция "exec" специально определяет байты 0x23 и 0x21, то наличие спецификации (0xEF 0xBB 0xBF) перед шебангом предотвратит выполнение интерпретатора сценария. Некоторые авторитетные специалисты рекомендуют не использовать знак порядка байтов в сценариях POSIX (Unix-подобных) по этой причине, а также из соображений большей совместимости и философских соображений. Кроме того, в UTF-8 нет необходимости в отметке порядка байтов, поскольку эта кодировка не имеет проблем с порядком байтов ; он служит только для идентификации кодировки как UTF-8.

Этимология

Исполняемый файл, начинающийся с директивы интерпретатора, просто называется сценарием, часто с префиксом имени или общей классификации предполагаемого интерпретатора. Имя shebang для двух отличительных символов могло появиться от неточного сокращения SHArp bang или haSH bang, относящихся к двум типичным для них именам Unix. Другая теория относительно sh в shebang заключается в том, что он взят из оболочки sh по умолчанию, обычно вызываемой с помощью shebang. Это использование было актуальным к декабрю 1989 года, а возможно и раньше.

История

Шебанг был представлен Деннисом Ричи между редакцией 7 и 8 в Bell Laboratories. Он также был добавлен к выпускам BSD от Berkeley's Computer Science Research (присутствует в 2.8BSD и активируется по умолчанию в 4.2BSD). Поскольку ATT Bell Laboratories Edition 8 Unix и более поздние версии не были выпущены для широкой публики, первое широко известное появление этой функции было на BSD.

Отсутствие директивы интерпретатора, но поддержка сценариев оболочки, очевидна в документации из версии 7 Unix в 1979 году, в которой вместо этого описывается средство оболочки Bourne, где файлы с исполнением разрешение будет обрабатываться специально оболочкой, которая (иногда в зависимости от начальных символов в сценарии, таких как «:» или «#») порождает подоболочку, которая интерпретирует и запускает команды, содержащиеся в файле. В этой модели сценарии будут вести себя как другие команды только в том случае, если они вызываются из оболочки Bourne. Попытка выполнить такой файл напрямую через системную ловушку exec () операционной системы потерпит неудачу, что не позволит сценариям вести себя единообразно как обычные системные команды.

В более поздних версиях Unix-подобных систем это несоответствие было устранено. Деннис Ричи представил поддержку ядром директив интерпретатора в январе 1980 года для версии 8 Unix со следующим описанием:

From uucp Thu Jan 10 01:37:58 1980

>От dmr, четверг, 10 января, 04:25:49 1980 г. удалено из исследования

Система была изменена так, что если исполняемый файл начинается с магических символов #! остальная часть строки считается именем интерпретатора для исполняемого файла. Раньше (и фактически до сих пор) оболочка выполняла большую часть этой работы; он автоматически запускался в текстовом файле в исполняемом режиме, когда имя текстового файла было введено в качестве команды. Включение объекта в систему дает следующие преимущества.

1) Это делает сценарии оболочки более похожими на настоящие исполняемые файлы, потому что они могут быть предметом 'exec'.

2) Если вы введете «ps» во время выполнения такой команды, вместо «sh» появится ее настоящее имя. Точно так же учет ведется на основе настоящего имени.

3) В сценариях оболочки можно указать идентификатор пользователя.

4) Проще иметь альтернативные оболочки; например Если вам нравится Berkeley csh, не возникает вопросов, какая оболочка должна интерпретировать файл.

5) Это позволит другим переводчикам более плавно вписаться.

Чтобы воспользоваться этой замечательной возможностью, введите

#! / bin / sh

в левом поле первой строки ваших сценариев оболочки. Пробелы после! ОК. Используйте полный путь (поиск не производится). На данный момент вся строка ограничена 16 символами, но этот предел будет увеличен.

Поддержка директив интерпретатора ядром распространяется на другие версии Unix, и одну современную реализацию можно увидеть в исходном коде ядра Linux в файле fs / binfmt_script.c.

Этот механизм позволяет использовать скрипты практически в любых Скомпилированные в контексте нормальные программы могут быть, в том числе, как полные системные программы, и даже как интерпретаторы других скриптов. Однако в качестве предостережения некоторые ранние версии поддержки ядра ограничивали длину директивы интерпретатора примерно до 32 символов (всего 16 в первой реализации), не могли бы отделить имя интерпретатора от любых параметров в директиве или имели другие причуды.. Кроме того, некоторые современные системы позволяют ограничивать или отключать весь механизм в целях безопасности (например, поддержка set-user-id отключена для скриптов во многих системах).

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

См. Также
Ссылки
Внешние ссылки
Последняя правка сделана 2021-06-08 04:20:07
Содержание доступно по лицензии CC BY-SA 3.0 (если не указано иное).
Обратная связь: support@alphapedia.ru
Соглашение
О проекте