Что является предпочтительным Bash shebang?

Есть ли какой-либо Bash shebang объективно лучше других для большинства применений?

  • #!/usr/bin/env bash
  • #!/bin/bash
  • #!/bin/sh
  • #!/bin/sh -
  • и т.д.

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

Ответ 1

Вы должны использовать #!/usr/bin/env bash для переносимости: разные * ники помещают bash в разные места, а использование /usr/bin/env - это обходной путь для запуска первого bash, найденного на PATH. И sh не является bash.

Ответ 2

/bin/sh обычно является ссылкой на системную оболочку по умолчанию, которая часто представляет собой bash, но, например, в системах Debian меньше вес dash. В любом случае, исходной оболочкой Bourne является sh, поэтому, если в вашем сценарии используются некоторые специфические функции bash (2-го поколения, "Bourne Again sh") ([[ ]] тесты, массивы, различные подсластители и т.д.), То Вы должны быть более конкретными и использовать позже. Таким образом, в системах, где bash не установлен, ваш скрипт не будет работать. Я понимаю, что может быть захватывающая трилогия фильмов об этой эволюции... но это может быть слухом.

Также обратите внимание, что когда вызывается как sh, bash в некоторой степени ведет себя как стандарт POSIX sh (см. также документ GNU об этом).

Ответ 3

Использование строки shebang для вызова соответствующего интерпретатора относится не только к BASH. Вы можете использовать shebang для любого интерпретируемого языка в вашей системе, например Perl, Python, PHP (CLI) и многие другие. Кстати, shebang

#!/bin/sh -

(он также может быть двумя тире, т.е. --) заканчивает bash параметры, после того как будут обработаны имена файлов и аргументы.

Использование команды env делает ваш script переносной и позволяет настраивать настраиваемые среды для вашего script, поэтому переносимые скрипты должны использовать

#!/usr/bin/env bash

Или для любого языка, такого как Perl

#!/usr/bin/env perl

Обязательно просмотрите страницы man для bash:

man bash

и env:

man env

Примечание. В системах на базе Debian и Debian, таких как Ubuntu, sh связан с dash not bash. Как и все системные сценарии, используйте sh. Это позволяет bash расти, и система остается стабильной, согласно Debian.

Кроме того, чтобы сохранить invocation * nix, как я никогда не использую расширения файлов для скриптов, выписанных shebang, так как вы не можете опустить расширение при вызове на исполняемые файлы, как вы можете в Windows. Команда файла может идентифицировать ее как script.

Ответ 4

Я рекомендую использовать:

#!/bin/bash

Он не на 100% переносим (некоторые системы размещают bash в месте, отличном от /bin), но тот факт, что многие существующие сценарии используют #!/bin/bash, заставляет различные операционные системы сделать /bin/bash по крайней мере символическая ссылка на основное местоположение.

Альтернатива:

#!/usr/bin/env bash
Было предложено

- но нет никакой гарантии, что команда env находится в /usr/bin (и я использовал системы там, где ее нет). Кроме того, эта форма будет использовать первый экземпляр bash у текущих пользователей $PATH, который может быть не подходящей версией оболочки bash.

Если вам нужен сценарий для запуска в системе, в которой нет /bin/bash, вы можете изменить сценарий так, чтобы он указывал на правильное местоположение (что, по общему признанию, неудобно).

Я более подробно обсудил компромиссы в моем ответе на этот вопрос.

Несколько неясное обновление: одна система, которую я использую, Termux, слой, похожий на десктоп, который работает под Android, не имеет /bin/bash (bash - /data/data/com.termux/files/usr/bin/bash) - но у него есть специальная обработка для поддержки #!/bin/bash.

Ответ 5

Это действительно зависит от того, как вы пишете сценарии bash. Если ваш /bin/sh символически связан с bash, когда bash вызывается как sh, некоторые функции недоступны.

Если вы хотите bash -специфические функции, отличные от POSIX, используйте #!/bin/bash