Если у меня есть test.sh:

#!/usr/bin/env bash
echo "$@"

bash test.sh результатов в 1

Есть идеи, почему результат равен 1? Кроме того, почему Shebang, чтобы env, а не напрямую Bash?

ОБНОВЛЕНИЕ: Извините, я пропустил некоторый код, который теперь имеет это, имеет смысл.

#!/usr/bin/env bash
main() {
  echo ${1:-1}
}
main "$@"

2 ответа2

0

Я не могу воспроизвести это на Ubuntu 18.04.1.

Вы должны проверить echo "$@" вне скрипта. Он покажет 1 если вы ранее набрали set 1 , или результаты любой предыдущей команды set позиционных параметров (в том числе в сценариях запуска).

Обратите внимание, что bash test.sh запускает test.sh как source файл (.) И любой #! линия игнорируется Действовать дальше !# вам понадобится:

bash -c test.sh

Что касается того, почему указан env , я понятия не имею, если только он не был добавлен в качестве заполнителя: он имел бы эффект, если бы он включал одну или несколько спецификаций среды. Например, следующее будет определять bash для запуска с пользовательским файлом запуска:

!#/usr/bin/env BASH_ENV=BashStart bash
...

Другая причина, предложенная ответом Атти, заключается в том, что в OSX bash по умолчанию не находится в /bin/ , а env находится в /usr/bin/ , как в Linux, поэтому !#/usr/bin/env bash позволяет указать bash в качестве оболочки в сценарии, который будет работать в Linux или OSX.

0

« Отсутствующий код » очень важен.

#!/usr/bin/env bash

main() {
  echo ${1:-1}
}

main "$@"

Здесь мы вызываем main функцию и предоставляем "${@}" (т.е. все наши аргументы, сохраняя разделение).

Когда ${@} расширяется до нуля (т. Е. Скрипт вызывался без аргументов), main() вызывается без аргументов, и, таким образом, ${1:-1} внутри функции main() будет иметь специальную эффект в соответствии с семантикой « Подстановка параметров ».

В частности, ${parameter:-default} будет расширяться до значения ${parameter} если он объявлен и не-NULL, или по default если он не объявлен или равен NULL. Обратите внимание, что ${parameter:-default} ведет себя несколько иначе, чем ${parameter-default} .

${parameter-default} и ${parameter:-default} почти эквивалентны. Extra : имеет значение только тогда, когда параметр был объявлен, но имеет значение null.

Таким образом, ${1:-1} будет расширяться до первого заданного аргумента или по умолчанию 1:

$ ./script.sh
1
$ ./script.sh test
test

Использование /usr/bin/env в shebang позволяет нам « использовать bash в качестве интерпретатора » без указания полного пути к bash ... env будет искать ${PATH} текущей среды и использовать для нас первый подходящий кандидат , Шебанг требует абсолютного пути к интерпретатору, и мы можем обойти это ограничение, используя env .

Это очень часто встречается в скриптах Python, поскольку интерпретатор может находиться в нескольких местах - хотя часто /usr/bin/python , он также поддерживает такие вещи, как virtualenv .

Смотрите " Почему люди пишут #!/usr/bin/env python shebang в первой строке скрипта Python?«для дальнейшего обсуждения.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .