В чем разница между #! / Bin / sh и #! / Bin / bash?

281

если я напишу,

#!/bin/bash
echo "foo"

или же

#!/bin/sh
echo "foo"

оба дают одинаковые. Я видел некоторые сценарии, начинающиеся с #!/bin/shили #!/bin/bash. Есть ли разница между ними?

Рахул Вирпара
источник

Ответы:

242

bashи shдве разные оболочки. В основном bashэто sh, с большим количеством функций и лучшим синтаксисом. Большинство команд работают одинаково, но они разные.

Сказав это, вы должны понимать, что /bin/shв большинстве систем будет символическая ссылка и не будет вызывать sh. В Ubuntu /bin/shраньше использовались ссылки на bashтипичное поведение в дистрибутивах Linux, но теперь оно изменилось на ссылки на другую оболочку, которая называется dash . Я бы использовал bash, так как это в значительной степени стандарт (или, по крайней мере, наиболее распространенный, из моего опыта). Фактически, проблемы возникают, когда сценарий bash будет использовать, #!/bin/shпотому что создатель сценария предполагает, что ссылка существует, bashкогда она не обязательна.

Для получения дополнительной информации, http://man.cx/sh , http://man.cx/bash .

reverendj1
источник
25
Ваш первый абзац вводит в заблуждение. «sh» - это вовсе не оболочка, а символическая ссылка на текущую настроенную системную оболочку , которая в системах Linux обычно представляет собой либо bash, либо dash (последние версии Ubuntu используют последнюю).
Томасруттер
19
/bin/shраньше это была оболочка, называемая оболочкой Борна, в 1977 году. bash - это оболочка, совместимая с / bin / sh, которая может использоваться в качестве замены оболочки Борна, которая соответствует посиксам. en.wikipedia.org/wiki/Bourne_shell
Алекс
5
Bash является стандартом де-факто (очень широко используется), но это не "стандарт"; sh в Ubuntu использует dash , который является Posix-совместимой оболочкой, поэтому он действительно стандартный. Мой совет - как можно чаще использовать тире для сценариев, особенно для сценариев на стороне сервера. Хотя Баш более выразительный, тир работает довольно много быстрее и более безопасные.
Рик-777
@ Rick-777 Так стоит ли явно ставить #! / Bin / dash наверху моих скриптов? Я также написал сценарии, где я пишу только команды и выполняю с ./scriptName, и это сработало нормально. Нужен ли #! / Bin / yourShell?
user137717
@ Rick-777 В тех случаях, когда я исключаю #! / Bin / shellName, я назвал файлы fileName.sh. Будет ли это косвенно ссылаться на предпочитаемую системную оболочку без объявления #! / Bin / sh?
user137717
82

В Linux и других Unix-подобных системах у вас есть выбор из нескольких оболочек.

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

bash - это самая распространенная оболочка, используемая в качестве оболочки по умолчанию для пользователей систем Linux. Это духовный потомок других оболочек, использовавшихся на протяжении всей истории Unix. Его имя, bash, является аббревиатурой от Bourne-Again Shell, дань уважения оболочке Bourne, которую она была разработана для замены, хотя она также включает в себя функции C Shell и Korn Shell.

В наши дни он запускается из /bin/bashлюбой системы с bash.

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

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

В верхней части сценария оболочки можно указать, какую оболочку следует запускать с использованием шебанга. Скрипт может указывать #!/bin/bashв первой строке, что означает, что скрипт всегда должен запускаться с bash, а не с другой оболочкой.

/ bin / sh - исполняемый файл, представляющий системную оболочку . Фактически, это обычно реализуется как символическая ссылка, указывающая на исполняемый файл для любой оболочки, являющейся системной оболочкой. Системная оболочка является своего рода оболочкой по умолчанию, которую должны использовать системные сценарии. В дистрибутивах Linux долгое время это обычно была символическая ссылка на bash , настолько, что стало условием всегда связывать / bin / sh с bash или bash-совместимой оболочкой. Однако в последние пару лет Debian (и Ubuntu) решили переключить системную оболочку с bash на dash- аналогичная оболочка - нарушение давней традиции в Linux (ну, GNU) использования bash для / bin / sh. Dash рассматривается как более легкая и намного более быстрая оболочка, которая может быть полезна для скорости загрузки (и других вещей, которые требуют много сценариев оболочки, таких как сценарии установки пакетов).

Dash довольно хорошо совместим с bash, основываясь на том же стандарте POSIX. Тем не менее, он не реализует специфичные для bash расширения. Существуют сценарии, которые используют #!/bin/sh(системную оболочку) в качестве своего шебанга, но для которых нужны специфичные для bash расширения. В настоящее время это считается ошибкой, которая должна быть исправлена Debian и Ubuntu, которым требуется / bin / sh, чтобы иметь возможность работать при указании на dash.

Даже несмотря на то, что системная оболочка Ubuntu указывает на dash, ваша оболочка входа в систему как пользователь продолжает быть bash в это время. То есть, когда вы входите в эмулятор терминала в любом месте Linux, ваша оболочка входа будет bash. Скорость работы не является большой проблемой, когда оболочка используется в интерактивном режиме, и пользователи знакомы с bash (и могут иметь специфичные для bash настройки в своем домашнем каталоге).

Что вы должны использовать при написании скриптов

Если вашему сценарию требуются функции, поддерживаемые только bash, используйте #!/bin/bash.

Но если это вообще возможно, было бы хорошо убедиться, что ваш сценарий совместим с POSIX, и использовать #!/bin/sh, что всегда и достаточно надежно, указывает на предпочтительную POSIX-совместимую системную оболочку в любой установке.

thomasrutter
источник
18

В дополнение к предыдущим ответам, даже если /bin/shэто символическая ссылка /bin/bash, #!/bin/shне полностью эквивалентна #!/bin/bash.

Из справочной страницы bash (1) :

«Если bash вызывается с именем sh, он пытается максимально близко имитировать поведение при запуске исторических версий sh, при этом также соответствует стандарту POSIX».

Например, специфичный для bash синтаксис:

 exec  > >(tee logfile.txt)

выдает ошибку в оболочке, начиная с #!/bin/shсимволической ссылки sh-> bash.

AnkiF
источник
6

GNU Bash: #!/bin/bash; POSIX оболочки: #!/bin/sh.

山 茶树 和 葡萄 树
источник
Ну, краткий, но точный ответ. 还 行
Сергей Колодяжный