Shebang (Шебанг) - это последовательность символов, состоящая из хэш-знака и восклицательного знака (#!). В Linux, Solaris, macOS, BSD и других системах на базе Unix он обычно используется в качестве первой строки в файлах сценариев для указания интерпретатора, который выполняет команды, присутствующие в файле.
В этом руководстве мы выясним различия между #!/usr/bin/bash и #!/usr/bin/env bash. Также мы обсудим их преимущества и недостатки.
Установка
Используя текстовый редактор типа nano, создадим и откроем исполняемый файл sample.sh:
1 | nano sample.sh |
Затем добавим в файл следующее содержимое:
1 2 | #!/usr/bin/bash echo "test scipt" |
Нам также нужно сделать файл скрипта исполняемым с помощью команды chmod:
1 | chmod u+x sample.sh |
Здесь флаг u+x предоставляет доступ к выполнению(x) текущему пользователю(u).
Мы будем использовать этот файл на протяжении всего учебника для тестирования поведения строк #!/usr/bin/bash и #!/usr/bin/env bash shebang.
Использование #!/usr/bin/bash
#!/usr/bin/bash - это строка Шебанг, используемая в файлах сценариев для установки bash, находящегося в каталоге '/bin', в качестве оболочки по умолчанию для выполнения команд, представленных в файле.
Она определяет абсолютный путь /usr/bin/bash к оболочке Bash. Обычно это местоположение оболочки Bash по умолчанию почти во всех операционных системах на базе Unix.
Чтобы узнать, где находится Bash в нашей системе, мы можем использовать команду which:
1 2 | which bash /usr/bin/bash |
Поскольку созданный нами sample.sh уже содержит эту строку shebang, давайте запустим его:
1 2 | ./sample.sh test scipt |
Мы также можем использовать строку #!/usr/bin/bash shebang для передачи дополнительных параметров интерпретатору оболочки:
1 | #!/usr/bin/bash -r |
Эта строка Шебанг используется для выполнения команд в интерпретаторе Bash. Параметр -r включает ограниченный режим оболочки.
Шебанг #!/usr/bin/bash рекомендуется, когда мы хотим точно указать абсолютный путь к интерпретатору. Он также имеет относительно высокую безопасность, и мы можем передавать дополнительные параметры.
С другой стороны, он плохо переносится, поскольку в разных системах интерпретаторы могут быть установлены в разных местах. Также может быть трудно запомнить абсолютный путь ко всем интерпретаторам, особенно в системах, где установлено несколько интерпретаторов, включая python, zsh, csh, ksh, sh и tcsh.
Использование #!/usr/bin/env bash
Как мы уже говорили, #!/usr/bin/env bash - это строка Шебанг, используемая в файлах сценариев для выполнения команд в оболочке Bash.
Она использует команду env для отображения переменных окружения, присутствующих в системе, а затем выполняет команды с помощью определенного интерпретатора.
Команда env работает, инструктируя систему искать указанный интерпретатор через переменную $PATH и использовать первый найденный. В системах на базе Unix она находится в каталоге "/usr/bin/env".
Мы можем проверить его расположение в нашей системе с помощью команды which:
1 2 | which env /usr/bin/env |
Давайте воспользуемся env для отображения всех текущих переменных окружения, определенных оболочкой:
1 2 3 4 5 6 7 | env SHELL=/bin/bash SESSION_MANAGER=local/user-PC:@/tmp/.ICE-unix/2839,unix/user-HP-Pavilion-g6-Notebook-PC:/tmp/.ICE-unix/2839 QT_ACCESSIBILITY=1 COLORTERM=truecolor ... |
Далее, воспользуемся grep для отображения $PATH из команды env:
1 2 3 | env | grep PATH WINDOWPATH=2 PATH=/home/username/.rbenv/shims:/home/username/.rbenv/bin:/home/username/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin |
Из приведенного выше результата видно, что $PATH содержит симлинки на /bin и другие каталоги, разделенные двоеточиями.
Чтобы проверить эту строку shebang, давайте сначала изменим первую строку файла sample.sh:
1 | #!/usr/bin/env bash |
Затем мы можем выполнить файл сценария:
1 2 | ./sample.sh test scipt |
Преимущество запуска файлов сценариев через /usr/bin/env заключается в автоматическом поиске версии интерпретатора по умолчанию в текущем окружении. Таким образом, нам не нужно искать его в определенном месте системы, поскольку в других системах пути могут отличаться.
Мы также можем указать версию интерпретатора, которая будет использоваться. Вот пример формата для указания версии интерпретатора Bash:
1 | #!/usr/bin/env bashX.x |
Шебанг #!/usr/bin/env bash обеспечивает большую переносимость, поскольку нам не нужно писать абсолютный путь к интерпретатору.
Однако он не поддерживает множественные параметры. Это связано с тем, что объявленный интерпретатор и его опция анализируются как один аргумент.
Кроме того, в случаях, когда в нашем окружении имеется несколько версий интерпретатора, это может привести к ошибкам, поскольку используется первый экземпляр bash, найденный в $PATH.
Сравнение
Вот таблица, показывающая сравнения между этими строками Шебанг:
#!/usr/bin/bash | #!/usr/bin/env bash |
Обеспечивает большую безопасность | Обеспечивает большую мобильность |
Более специфично, поскольку мы должны объявить точный путь к интерпретатору | Автоматически ищет первое появление интерпретатора в окружении |
Может поддерживать дополнительные параметры, передаваемые после объявления интерпретатора | Не может поддерживать дополнительные параметры, потому что система считывает их как одну команду |
Заключение
В этой статье мы рассмотрели различия между строками #!/usr/bin/bash и #!/usr/bin/env bash shebang. Мы также рассмотрели их преимущества и недостатки.
Мы можем использовать любую из них для выполнения команд в сценариях оболочки Bash или любой другой оболочки. Однако рекомендуется использовать #!/usr/bin/bash, если безопасность является приоритетом, и #!/usr/bin/env bash, если мы стремимся к переносимости.