Я прочитал следующее в этом вопросе :
bash поддерживает ключ --posix, что делает его более совместимым с POSIX. Он также пытается имитировать POSIX, если вызывается как sh .
Выше цитата предполагает, что /bin/sh
это ссылка, на которую указывает /bin/bash
.
Но я не совсем понимаю, что подразумевается под словом «вызывается как sh» .
Скажем, у меня есть следующий скрипт, который называется "script.sh":
#!/bin/bash
echo "Hello World"
Пожалуйста, скажите мне в каждом из следующих случаев, будет ли скрипт выполняться в обычном bash
режиме или в режиме POSIX (предположим, что я выполнил следующие команды в работающем терминале bash
):
sh script.sh
bash script.sh
./script.sh
Теперь скажите, что у меня есть следующий скрипт, который называется «script.sh» (который похож на скрипт выше, но без шебанга):
echo "Hello World"
Пожалуйста, скажите мне в каждом из следующих случаев, будет ли скрипт выполняться в обычном bash
режиме или в режиме POSIX (предположим, что я выполнил следующие команды в работающем терминале bash
):
sh script2.sh
bash script2.sh
./script2.sh
Ответы:
Только случаи 1 и 4 будут работать в режиме POSIX (при условии, что
sh
это bash, а не какая-то другая реализация sh). Любой случай, который явно вызываетbash
без--posix
воли не будет, будь то Шебанг или нет. Любой случай, который явно вызывает,sh
будет. Шебанг используется только тогда, когда для сценария уже явно не запущена оболочка.Случай 6, если ваш терминал работает
bash
, не будет работать в режиме POSIX, и Bash вызовет его, используя себя. Если ваш терминал был запущен ЗШ вместо этого, случай 6 будет также работать в режиме POSIX. POSIX неоднозначно относится именно к тому, что должно произойти в этом случае , и Bash и zsh сделали там разные выборы. Bash вызывает скрипт используя себя, а zsh используетsh
(что бы это ни было). Другие оболочки также различаются по этому вопросу.Один простой способ узнать, в каком режиме вы находитесь - создать тело скрипта:
которая завершится с ошибкой в режиме POSIX , но даст инструкции по использованию за ее
kill
пределами. Это простое различие, и оно работает через широкий диапазон версий Bash, начиная с того, с чем вы, вероятно, столкнетесь.источник
bash
работать в режиме POSIX, такие какPOSIXLY_CORRECT
переменная окружения илиSHELLOPTS=posix
.[ -o posix ]
это более очевидный способ проверить, что вы работаете в режиме posix в bash (не в других оболочках (кроме yash), поэтому вы не захотите делать это вsh
скрипте).POSIXLY_CORRECT=1 bash -c '[ -o posix ] && echo yes'
выводитyes
`«Вызывается как» относится к тому , что это то , что процесс запуска Bash ставит в своей «нулевой» аргумент командной строки,
argv[0]
.Когда программа запускается с
exec*()
системными вызовами , они на самом деле не узнают имя двоичного файла, содержащего программу, но вместо этого вызывающий процесс может свободно поместить туда все, что захочет. Обычно, конечно, имя берется из файловой системы, так что если вы запустите/bin/sh
, это то, что там будет помещено. И если/bin/sh
это Bash, это не должна быть символическая ссылка, это может быть жесткая ссылка или просто еще одна копия программы оболочки.В качестве примера установки «имени программы»
exec
команда Bash может установить нулевой аргумент с-a
параметром. (Мы можем сделать то же самое с Perl или напрямую с C и т. Д.)Вот
myname
простая C-программа, которая просто печатает свой нулевой аргумент, имя, которое она видит сама:Источник:
Но, чтобы ответить на пронумерованные вопросы ...
(1 и 4) бег
sh somescript
будет работать, чтоsh
на васPATH
, вероятно,/bin/sh
но, возможно, что-то вроде/usr/xpg4/bin/sh
.sh
.sh
, но работает в режиме «SH-совместимости», который нацелен на совместимость с оболочкой Bourne и слегка отличается от режима полного соответствия POSIX в обеих этих оболочках. ,(2 и 5) Запуск
bash somescript
будет выполняться в обычном режиме Bash (опять же, это, конечно, зависит от того, чтоbash
у васPATH
есть.)(3) Здесь имя сценария присваивается непосредственно системному вызову вместо файла программы. Ядро читает строку hashbang и использует ее для запуска скрипта.
(6) Это сложный. Это похоже на (3), но системный вызов для запуска программы завершается с ошибкой (
ENOEXEC (Exec format error)
), так как нет строки hashbang. Что произойдет дальше , зависит от того , является ли оболочка , что вы работаете на себя в режиме POSIX. POSIX требует, чтобы POSIX-совместимая оболочка вела себя особым образом в ответ наENOEXEC
. Однако в «команде, эквивалентной вызову оболочки», есть некоторая свобода действий, которая означает, что разные оболочки делают разные вещи./bin/sh
с именем сценария, вставленным перед остальными аргументами в качестве первого аргумента командной строки. Оболочка Z, оболочка Almquist и оболочка Korn (пытаются) вызвать POSIX-совместимую оболочку, предполагая, что/bin/sh
программа одна.источник
int main(int argc, char *argv[]){printf("I am %s\n",argv[0]);}
Выполняемая оболочка - это либо вызываемая в командной строке, либо оболочка в shebang (если в командной строке это не указано).
Итак, версии 1 и 4 будут работать с
sh
, 2 и 5 с bash, а 6 может не работать, если вы используете sh (и некоторые другие) в интерактивном режиме. Bash запускает скрипт. Кш тоже. Зш начинает это как ш.Только те, кто запущен как,
sh
будут использовать опцию posix, если bash связан с/bin/sh
.Добавьте эту строку в ваш скрипт, чтобы определить, работает ли какая-либо версия bash ksh или zsh:
источник