
Я читал вдругой ответчто я не могу передать интерпретатору аргументы, отличные от тех, которые я передаю /usr/bin/env
:
Другая потенциальная проблема заключается в том, что этот
#!/usr/bin/env
трюк не позволяет передавать аргументы интерпретатору (кроме имени скрипта, которое передается неявно).
Однако, похоже, мне это удаётся, потому что awk
он ломается, когда я не устанавливаю флаг, -f
и чинится, когда я устанавливаю флаг -f
, при использовании /usr/bin/env
:
Сначала без -f
флага:
$ cat wrap_in_quotes
#!/usr/bin/env awk
# wrap each line in quotes
# usage: wrap_in_quotes [ file ... ]
{ print "\""$0"\"" }
$ echo foobar | ./wrap_in_quotes
awk: syntax error at source line 1
context is
>>> . <<< /wrap_in_quotes
awk: bailing out at source line 1
Во-вторых, с -f
флагом:
$ vim wrap_in_quotes
$ cat wrap_in_quotes
#!/usr/bin/env awk -f
# wrap each line in quotes
# usage: wrap_in_quotes [ file ... ]
{ print "\""$0"\"" }
$ echo foobar | ./wrap_in_quotes
"foobar"
- Итак, если согласносвязанный ответЯ не могу передать флаги интерпретатору. Почему я могу передать
-f
флагawk
?
Я бегу macOS
:
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.12.1
BuildVersion: 16B2657
решение1
Некоторые Unix-системы, в частности macOS (и до 2005 года FreeBSD), позволяют это делать, тогда как Linux — нет, но...
Если использовать env
утилиту из недавнего выпуска пакета GNU coreutils (8.30+), то в ней есть нестандартная -S
опция, позволяющая указывать несколько аргументов в #!
строках.
Обратный вопрос:Строка Shebang с `#!/usr/bin/env command --argument` не работает в Linux
решение2
Вы не можетепортативнопередавать интерпретатору несколько аргументов. В частности, Linux это не поддерживает.
Некоторые варианты Unix поддерживают более одного аргумента в строке shebang. Это касается современных систем macOS и некоторых других. СмотретьСтраница Свена Машека о переносимости оболочкидляСравнительная таблица вариантов Unixи много исторической информации.
Если вам нужен переносимый скрипт awk, то нет четкого решения. #!/usr/bin/env
и #!/bin/sh
являются единственными строками shebang, которые переносимы на практике: в зависимости от варианта Unix, awk
могут быть в /bin
или /usr/bin
, или в некоторых других местах (например, /usr/xpg4/bin/awk
в Solaris, чтобы получить POSIX — тот, что в /usr/bin
предназначен для устаревших приложений). Поскольку #!/usr/bin/env awk -f
не работает переносимо, остается #!/bin/sh
. ( /bin/sh
может быть устаревшей оболочкой Bourne, а не современной оболочкой POSIX, но любая платформа Unix имеет что-то там на практике.) Идея состоит в том, чтобы написатьполиглот, т. е. скрипт, который sh
интерпретируется как инструкции для запуска awk, а awk интерпретирует его как желаемый скрипт. Это работает даже в системах, которые не распознают строки shebang, но по умолчанию используют sh
для выполнения скрипта (некоторые старые unice или некоторые unix-подобные пользовательские пространства на не-Unix-ядрах).
#!/bin/sh
"exec" "awk" "-f" "$0" "$@" && 0 {}
… # awk script here
(Если вас беспокоит возможность переносимости на старые юниксы, см.Страница Свена Машекана "$@"
поддержку и рассмотрите возможность использования ${1+"$@"}
вместо этого.)