На странице языка команд оболочки спецификации POSIX:
Если первая строка файла команд оболочки начинается с символов «#!», Результаты не указываются.
Почему поведение #!
не определено POSIX? Я нахожу странным, что что-то такое портативное и широко используемое будет иметь неопределенное поведение.
exec()
функцию. Поэтому проверка на наличие нескольких оболочек на самом деле не говорит вам, насколько она портативна.Ответы:
Я думаю, прежде всего потому, что:
поведение сильно варьируется в зависимости от реализации. Смотрите https://www.in-ulm.de/~mascheck/various/shebang/ для всех деталей.
Однако теперь он может указывать минимальное подмножество большинства реализаций, подобных Unix: например,
#! *[^ ]+( +[^ ]+)?\n
(если в этих одном или двух словах заданы только символы из переносимого набора символов имени файла), когда первое слово представляет собой абсолютный путь к собственному исполняемому файлу, слишком длинный и поведение не определено, если исполняемый файл setuid / setgid, и реализация определяет, передается ли интерпретатору путь интерпретатора или путь сценарияargv[0]
.POSIX в любом случае не указывает путь к исполняемым файлам. В некоторых системах есть утилиты pre-POSIX в
/bin
//usr/bin
и утилиты POSIX где-то еще (как в Solaris 10, где/bin/sh
есть оболочка Bourne, а в POSIX - одна/usr/xpg4/bin
; Solaris 11 заменил ее на ksh93, которая более совместима с POSIX, но большинство других инструменты/bin
все еще древние не POSIX). Некоторые системы не POSIX, но имеют режим / эмуляцию POSIX. Все, что требуется POSIX - это наличие документированной среды, в которой система ведет себя POSIXly.См. Например, Windows + Cygwin. На самом деле, с Windows + Cygwin, она взволнована, когда сценарий вызывается приложением cygwin, но не собственным приложением Windows.
Таким образом, даже если в POSIX указан механизм shebang, его нельзя использовать для написания сценариев POSIX
sh
/sed
/awk
... (также обратите внимание, что механизм shebang нельзя использовать для написания надежного сценарияsed
/awk
сценария, так как он не позволяет передавать конец опции маркер).Теперь тот факт, что он не указан, не означает, что вы не можете его использовать (ну, это говорит о том, что первая строка не должна начинаться с того,
#!
что вы ожидаете, что это будет только обычный комментарий, а не чёртов), но что POSIX не дает вам никакой гарантии, если вы это сделаете.По моему опыту, использование shebangs дает вам больше гарантий переносимости, чем использование POSIX-сценария написания сценариев оболочки: откажитесь от she-bang, напишите сценарий с
sh
синтаксисом POSIX и надейтесь, что все, что вызывает сценарий, вызывает для него POSIX-совместимостьsh
, хорошо, если вы знаете, что скрипт будет вызываться в правильной среде правильным инструментом, но не иначе.Возможно, вам придется делать такие вещи, как:
Если вы хотите быть переносимым на Windows + Cygwin, возможно , придется назвать свой файл с
.bat
или.ps1
расширением и использовать некоторый подобный трюк дляcmd.exe
илиpowershell.exe
вызвать Cygwinsh
на том же файле.источник
sh
, ему не понадобилась бы строка hashbang, как это было бы выполнено POSIXsh
.execlp
илиexecvp
были использованы, верно? Если бы я использовалexecve
, это привело бы к ENOEXEC?Вы не смотрите достаточно глубоко.
Еще в 1980 - х годах, этот механизм был не де - факто стандартизирован. Несмотря на то, что Деннис Ритчи это реализовал, эта реализация не достигла широкой публики в области AT & T во вселенной. Это было эффективно только публично доступно и известно в BSD; с исполняемыми сценариями оболочки, недоступными в AT & T Unix. Таким образом, было не разумно стандартизировать это. Положение вещей иллюстрируется этим современным документом, одним из многих таких:
- Стивен Фреде (1988). "Программирование в System X Release Y". Австралийский Unix Systems User Group Информационный бюллетень . Том 9. Номер 4. с. 111.Важным моментом здесь является то, что вы смотрите на оболочки, в то время как наличие исполняемых сценариев оболочки на самом деле
exec…()
зависит от функций. То, что делают оболочки, включает в себя предшественники механизма исполняемых сценариев, которые все еще можно найти в некоторых оболочках даже сегодня (а также в настоящее время обязательные дляexec…p()
подмножества функций), и это несколько вводит в заблуждение. В этом отношении стандарт должен учитывать то, какexec…()
работает интерпретируемый сценарий, и в то время, когда POSIX был изначально создан, он просто не работал в первую очередь в большей части спектра целевых операционных систем .Подчиненный вопрос, почему это не было стандартизировано , так как, в частности , как механизм магического числа для сценария переводчиков был достигнута общественность в AT & T стороны Вселенной и был задокументирован для
-exec…()
в определении 5 Интерфейса системы , на рубеже 1990 - х лет :exec
. V Интерфейс Определение системы . Том 1. 1991.К сожалению, поведение остается сегодня почти таким же широко расходящимся, как это было в 1980-х годах, и нет действительно распространенного поведения, которое можно стандартизировать. Некоторые Unices (например, HP-UX и FreeBSD, например) не поддерживают сценарии как интерпретаторы сценариев. То, является ли первая строка одним, двумя или многими элементами, разделенными пробелами, зависит от MacOS (и версий FreeBSD до 2005 года) и других. Максимальная поддерживаемая длина пути варьируется.
␀
и символы из набора символов переносимого имени файла POSIX являются хитрыми, как начальные и конечные пробелы. То, чем заканчиваются 0-й, 1-й и 2-й аргументы, тоже сложно, со значительными различиями в разных системах. Некоторые в настоящее время POSIX-совместимые, но не- Системы Unix по-прежнему не поддерживают ни один такой механизм, и его обязательное преобразование приведет к тому, что они перестанут быть POSIX-совместимыми.дальнейшее чтение
script
, NetBSD Разное информационное руководство . 2005-05-06.источник
Как отмечается в некоторых других ответах, реализации различаются. Это затрудняет стандартизацию и сохранение обратной совместимости с существующими сценариями. Это верно даже для современных систем POSIX. Например, Linux не полностью разбивает строку shebang на пробелы. macOS не позволяет интерпретатору сценария быть другим сценарием.
Также смотрите http://en.wikipedia.org/wiki/Shebang_(Unix)#Portability
источник