Из Википедии, свободной энциклопедии
Перейти к навигации Перейти к поиску

В вычислениях , притон является последовательность символов , состоящая из символов знака числа и восклицательный знак ( #! ) В начале сценария . Это также называется sha-bang , [1] [2] hashbang , [3] [4] pound-bang , [5] [6] или hash-pling . [7]

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

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

Синтаксис [ править ]

Форма директивы интерпретатора shebang следующая: [8]

#! интерпретатор [ необязательный аргумент ]

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

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

В 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 / С .

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

Примеры [ править ]

Некоторые типичные строки шебанга:

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

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

Цель [ править ]

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

Борна оболочки сценарий , который идентифицируется по пути некоторые / путь / к / Foo , имеет начальную строку,

#! / bin / sh -x

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

некоторый / путь / к / foo bar baz

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

/ bin / sh -x некоторые / путь / к / foo bar baz

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

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

#! / bin / catПривет мир!

Сильные стороны [ править ]

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

Переносимость [ править ]

Местоположение программы [ править ]

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

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

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

Часто для обхода этого ограничения можно использовать программу / 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, не разделяют аргументы; [16] например, при запуске скрипта с первой строкой вида,

#! / usr / bin / env python3 -c

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

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

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

Магическое число [ править ]

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

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

Этимология [ править ]

Исполняемый файл, начинающийся с директивы интерпретатора, просто называется сценарием, часто перед ним указывается имя или общая классификация предполагаемого интерпретатора. Название притон для отличительных двух знаков может исходить от неточного сокращения из - диез взрыва или хэш - функции взрыва , ссылаясь на два типичных имен Unix для них. Другая теория относительно sh в shebang заключается в том, что он взят из оболочки sh по умолчанию , обычно вызываемой с помощью shebang. [23] Это использование было актуальным к декабрю 1989 г. [24] и, вероятно, раньше.

История [ править ]

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

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

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

От UUCP Чт 10 января, 01:37:58 1980

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

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

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

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

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

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

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

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

 #! / bin / sh

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

Однако создатель функции не дал ей названия: [27]

От: "Ричи, Деннис М (Деннис) ** CTR **" <dmr @ [отредактировано]>Кому: <[отредактировано] @ talisman.org>Дата: 19 ноября 2009 г., 18:37:37 -0600Тема: RE: Как -вы- называете свою линию #! <something>? Не могу вспомнить, чтобы мы когда-либо давали ему собственное имя.Было довольно поздно, что это вошло - я думаю, что яполучил идею от кого-то на одной из конференций UCBна Berkeley Unix; Возможно, я был одним из первых, ктона самом деле установить его, но это была идея, которую я получилоткуда-нибудь.Что касается названия: наверное, что-то описательное вроде"хэш-бэнг" хоть и имеет специфически британский колорит, нов любом случае я не припомню, чтобы особо использовал кличку питомцадля строительства.

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

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

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

См. Также [ править ]

  • binfmt_misc
  • CrunchBang Linux
  • Файловая ассоциация
  • Фрагмент URI

Ссылки [ править ]

  1. ^ «Advanced Bash Scripting Guide: Глава 2. Начиная с Sha-Bang» . Архивировано 10 декабря 2019 года . Проверено 10 декабря 2019 .
  2. Купер, Мендель (5 ноября 2010 г.). Advanced Bash Scripting Guide 5.3 Том 1 . lulu.com. п. 5. ISBN 978-1-4357-5218-4.
  3. ^ Макдональд, Мэтью (2011). HTML5: Отсутствующее руководство . Севастополь, Калифорния: O'Reilly Media . п. 373. ISBN. 978-1-4493-0239-9.
  4. Перейти ↑ Lutz, Mark (сентябрь 2009 г.). Изучение Python (4-е изд.). O'Reilly Media . п. 48. ISBN 978-0-596-15806-4.
  5. ^ Guelich, Gundavaram и Birznieks, Скотт, Шишир и Гюнтер (29 июля 2000). Программирование CGI с помощью PERL (2-е изд.). O'Reilly Media . п. 358 . ISBN 978-1-56592-419-2.
  6. ^ Ли Hetland, Magnus (4 октября 2005). Начиная с Python: от новичка до профессионала . Апресс. п. 21. ISBN 978-1-59059-519-0.
  7. ^ Schitka, Джон (24 декабря 2002). Linux + Руководство по сертификации Linux . Курсовая технология. п. 353. ISBN. 978-0-619-13004-6.
  8. ^ a b "execve (2) - справочная страница Linux" . Проверено 21 октября 2010 года .
  9. Корбет, Джонатан. «Дело о крупногабаритном шебанге» . LWN.net .
  10. ^ "SRFI 22" .
  11. ^ https://stackoverflow.com/questions/45444823/python3-shebang-line-not-working-as-expected
  12. ^ "Проблема 7 Базовых спецификаций Открытой группы" . 2008 . Проверено 5 апреля 2010 года .
  13. ^ "pixelbeat.org: Распространенные ошибки сценариев оболочки" . Гораздо лучше тестировать скрипты непосредственно в POSIX-совместимой оболочке, если это возможно. Опция `bash --posix` недостаточна, так как она все еще принимает некоторые` `башизмы ''
  14. ^ «Глава 2. Язык команд оболочки» , Базовые спецификации Open Group (IEEE Std 1003.1-2017) (выпуск 7 изд.), IEEE, 2018 [2008], Если первая строка файла команд оболочки начинается с символов «#!», результаты не указаны.
  15. ^ Autoconf , Free Software Foundation, макрос: AC_SYS_INTERPRETER: проверьте, поддерживает ли система запуск сценариев со строкой вида '#! / Bin / sh', чтобы выбрать интерпретатор, который будет использоваться для сценария.
  16. ^ "/ usr / bin / env behavior" . Mail-index.netbsd.org. 9 ноября 2008 . Проверено 18 ноября 2010 года .
  17. ^ env(1)  -  Руководство по основным командам FreeBSD
  18. ^ "env invocation" . GNU Coreutils . Дата обращения 11 февраля 2020 .
  19. ^ «Возврат каретки приводит к сбою bash» . 8 ноября 2013 г.
  20. ^ "Руководство GNU Autoconf v2.57, Глава 10: Программирование переносимой оболочки" . Архивировано из оригинала 18 января 2008 года . Дата обращения 14 мая 2020 .
  21. ^ «Магия #!, Подробности о механизме shebang / hash-bang в различных версиях Unix» . Дата обращения 14 мая 2020 .
  22. ^ "Часто задаваемые вопросы - UTF-8, UTF-16, UTF-32 и спецификация: может ли поток данных UTF-8 содержать символ спецификации (в форме UTF-8)? Если да, то могу ли я предположить, что оставшийся UTF-8 байты находятся в обратном порядке? " . Проверено 4 января 2009 года .
  23. ^ "Запись файла жаргона для shebang" . Catb.org . Проверено 16 июня 2010 года .
  24. ^ Wall, Ларри . «Perl не находил сценарии setuid, у которых в первой строке между shebang и именем интерпретатора был пробел» . USENET .
  25. ^ a b "CD-ROM с архивом CSRG" .
  26. ^ СИСТЕМА РАСПРЕДЕЛЕНИЯ ВРЕМЕНИ UNIX: РУКОВОДСТВО ПРОГРАММИСТА UNIX (PDF) , 2A (седьмое изд.), Январь 1979 г.
  27. ^ Ричи, Деннис. «Деннис Ричи и Hash-Bang» . Talisman.org . Дата обращения 3 декабря 2020 .
  28. ^ Рубини, Alessandro (31 декабря 1997). «Игра с двоичными форматами» . Linux Journal . Проверено 1 января 2015 года .

Внешние ссылки [ править ]

  • Подробная информация о механизме shebang в различных версиях Unix
  • #! - правда о Unix, насколько мне известно (более общий подход)
  • FOLDOC shebang статья