Я тестирую простой скрипт, и мне интересно, почему он отлично работает при запуске из каталога: ./test.sh
но когда я пытаюсь использовать команду "sh" sh test.sh
это не работает:
test.sh: 3: test.sh: [[: not found
test.sh: 7: test.sh: [[: not found
Сценарий:
#!/usr/bin/env bash
if [[ $1 = one ]]
then
printf "%b" "two\n" >&2
exit 0
elif [[ $1 = two ]]
then
printf "%b" "one\n" >&2
exit 0
else
printf "%b" "Specify argument: one/two\n"
exit 1
fi
sh
это другая программа, чем bash
.
Проблема в том, что оболочка Борна (sh
) не является оболочкой Bourne Again (bash
). А именно sh не понимает [[
прагма. На самом деле он не понимает [
либо. [
это фактическая программа или ссылка на / bin / test (или / usr / bin / [, / usr / bin / test).
$ which [
/bin/[
$ ls -lh /bin/[
-r-xr-xr-x 2 root wheel 42K Feb 29 17:11 /bin/[
Когда вы выполняете свой скрипт напрямую через ./test.sh
, вы вызываете сценарий в качестве первого аргумента программы, указанной в первой строке. В таком случае:
#!/usr/bin/env bash
Часто это напрямую интерпретатор (/bin/bash
или любое количество других интерпретаторов скриптов), но в вашем случае вы используете env для запуска программы в измененной среде, но этот следующий аргумент по-прежнему является bash. Фактически, ./test.sh
является bash test.sh
.
Так как sh
и bash
это разные оболочки с разной интерпретацией синтаксиса, вы видите эту ошибку. Если ты бежишь bash test.sh
, вы должны увидеть то, что ожидается.
Другие отметили в комментариях, что /bin/sh
может быть ссылка или другая оболочка. Исторически, sh
была оболочкой Борна в старой AT&T Unix и, на мой взгляд, каноническим происхождением. Однако это отличается в вариациях BSD и со временем разошлось в других системах и дистрибутивах на основе Unix. Если вас действительно интересует внутренняя работа (включая то, как / bin / sh и / bin / bash могут быть одной и той же программой и вести себя совершенно по-разному), прочтите следующее:
Как уже отмечалось: / bin / sh обычно (хотя и не всегда) вызывает POSIX-совместимую оболочку Bourne. Баш - это не Борн.
Bash попытается имитировать Борна при вызове как 'sh' (например, когда символические ссылки / bin / sh или ссылки на / bin / bash) или если $ POSIXLY_CORRECT определен в вызывающей среде, при вызове с параметром вызова --posix, или когда было выполнено 'set -o posix'. Это позволяет протестировать сценарий / команду оболочки Bourne на соответствие POSIX.
Как вариант, запускайте сценарии / тестовые команды с известной POSIX-совместимой оболочкой. «тире» близко, оболочка Korn (ksh) IIRC также предлагает вариант, совместимый с POSIX.