Это ловушка попыток установить параметры в строке #!
.Ядро разбивает строку shebang только на первый пробел.
Когда вы говорите
#!/bin/zsh -o pipefail
, команда, которая заканчивается выполнением, является "/bin/zsh" "-o pipefail" "/home/prajjwal/script"
.
Ошибкасообщение говорит, что " pipefail"
(обратите внимание на начальный пробел) не является допустимой опцией, которая является правильной: допустим только "pipefail"
.
В этом случае возможный обходной путь - собрать все в одну командную строкуаргумент:
#!/bin/zsh -opipefail
Но в целом это невозможно, и интерфейс #!
не позволяет передавать более одного дополнительного аргумента, поэтому вы можете найти другие обходные пути (например, используя set
вручную) или написать скрипт-обертку:
#!/bin/zsh
exec /bin/zsh -o pipefail /path/to/the/real/script
В некоторых системах доступна другая альтернатива: env -S
.Эта опция не указана в POSIX и доступна не во всех системах.Он работает на системах с использованием инструментов GNU (включая все стандартные дистрибутивы Linux) и FreeBSD , но не OpenBSD или NetBSD .Я не смог найти никакой информации о MacOS.
(Примечание: GNU env также поддерживает --split-string
в качестве альтернативного (длинного) имени опции, но FreeBSD env нет.)
Использование:
#!/usr/bin/env -S /bin/zsh -o pipefail
Это вызывает env
с одним длинным аргументом ('-S /bin/zsh -o pipefail'
).Обработка стандартного параметра обрабатывает его как параметр -S
, за которым следует аргумент (' /bin/zsh -o pipefail'
).
В таком простом случае, как этот, env -S
разбивает аргумент на пробелы / табуляции и обрабатывает полученный список какесли она изначально была частью исходной командной строки:
env -S ' /bin/zsh -o pipefail'
# works the same as:
env /bin/zsh -o pipefail
В менее простых случаях вам придется заключать в кавычки некоторые символы (env -S
обрабатывает пробелы, "
, '
, \
, $
специально, среди прочих).В частности, он не работает как цитирование оболочки.Подробнее см. На страницах руководства, ссылки на которые приведены выше.