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

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

#!/bin/bashecho "foo"

или

#!/bin/shecho "foo"

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

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.

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

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

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

В наши дни он управляется из /bin/bash - любая система с bash будет доступна здесь.

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

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

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

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

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

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

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

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

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

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

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

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

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

 exec  > >(tee logfile.txt)

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

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