Gawk обычно находится в / bin или / usr / bin? Я бы пошел с, #!/usr/bin/env gawk
но тогда я не могу использовать аргументы. Щас пользуюсь #!/bin/gawk -f
. Скрипт очень длинный, содержит много одинарных кавычек и работает с stdin.
В руководстве по GNU Awk есть раздел 1.1.4 Исполняемые программы awk, в котором в его примере используется #! / Bin / awk, но далее говорится:
Обратите внимание, что во многих системах
awk
можно найти в/usr/bin
вместо/bin
. Пусть покупатель будет бдителен.
Что делает большинство людей? Я читал, что sed предположительно стандартизирован в / bin, тогда как perl предположительно стандартизирован в / usr / bin (та же страница, что и в ссылке sed, но они не позволят мне сделать третью ссылку для этого поста). Как насчет awk / gawk? Кто-нибудь знает, что является более распространенным или популярным?
-f
? Не/bin/gawk
достаточно? Также это может быть актуально.Ответы:
Шебанг не должен был быть таким гибким . Могут быть случаи, когда работает второй параметр , я думаю, что FreeBSD - один из них.
gawk и большинство утилит, которые поставляются с ОС, как ожидается, будут в
/usr/bin/
.В прежние времена UNIX было принято
/usr/
монтировать через NFS или какой-либо менее дорогой носитель, чтобы сэкономить место на локальном диске и затраты на рабочую станцию./bin/
должен был иметь все необходимое для загрузки в однопользовательском режиме . Поскольку/usr/
он не был смонтирован на надежном носителе, в него было/bin/
включено достаточно утилит, чтобы сделать его достаточно дружественным для общего администрирования и устранения неполадок.Первоначально это было унаследовано в Linux, но, поскольку дисковое пространство больше не является проблемой и в большинстве случаев
/usr/
находится в корневой файловой системе, текущая тенденция состоит в том, чтобы переместить все в/usr/bin
(по крайней мере, в мире Linux). Поэтому ожидается, что большинство утилит, установленных дистрибутивом, будут там. Даже самые основные утилиты, какcp
,rm
, иls
т.д. (ну, еще нет).Относительно выбора Шебанга. Традиционно это то, что администраторы или пользователи должны редактировать в соответствии со своей средой. Насколько известно разработчику, в системах других людей интерпретатор может находиться где угодно в файловой системе (например
/usr/local/bin
,/opt/gawk-4.0.1/bin
). Правильно упакованные сценарии (rpm, deb и т. Д.) Поставляются с зависимостью от пакета дистрибутива (т. Е. Интерпретатор имеет известное местоположение) или сценарием конфигурации, который устанавливает надлежащий hashbang во время установки.источник
Если вам не нужно передавать аргументы в команду, то
#!/usr/bin/env gawk
это путь, однако многие ядра (включая Linux) принимают только один аргумент для программ shebang.В противном случае вы можете создать программу polyglot, которая является одновременно оболочкой оболочки и сценарием awk. Вот один для awk.
Разбор оболочки:
true + /;
- командаtrue
(которая ничего не делает) с двумя инертными аргументами+
и/
.gawk
. Это может быть любой фрагмент оболочки, который не содержит символов новой строки и где пишется косая черта\/
(оболочка не возражает, кроме как внутри кавычек).Вызов использует
exec
для замены оболочки gawk вместо выполнения gawk в качестве подпроцесса.exit;
- выйти из корпуса, если не было обнаружено gawk. Все, что после этого игнорируется, за исключением того, что это должен быть допустимый синтаксис оболочки на случай, если оболочка попытается проанализировать всю строку перед началом ее выполнения.Разбор Awk:
true + /REGEX/
- состояние.true
является неопределенной переменной, поэтому ее числовое значение равно 0, а не то, что это имеет значение.{}
- Если указанное условие выполняется, ничего не делать.источник
Предложенное Жилем решение действительно является очень хорошим подходом (наконец, имейте репутацию, чтобы голосовать на своем посту :)).
В любом случае, насколько я понимаю,
exec
команда делает ееexit
правой после ненужной, фактически недоступной, так как процесс оболочки заменяется наawk
.Кроме того, чтобы
awk
скрипт мог получить доступ к своим параметрам вызова, я бы предложил некоторые изменения в предлагаемом решении:-a "$0"
Позволяет сценарий , чтобы иметь доступ к его имени вызова, в противном случае он всегда будет получитьawk
илиgawk
при обращении кARGV[0]
переменной. Точно так же,"$@"
позволяет скрипту получить доступ к остальным параметрам вARGV[1...N]
массиве, а--
предшествующее ему позволяет скрипту получать-<something>
аргументы без их интерпретации gawk.Одна вещь, которую следует запомнить / рассмотреть, это добавить
exit(0);
оператор в конецBEGIN { ... }
блока программы-awk
скрипта, иначе онawk
будет представлять угрозу для всех параметров, передаваемых в скрипт как входные файлы. (Обратите внимание, что это никак не связано сexit
оператором, который мы удалили изtrue + ...
строки, это был недостижимый оператор оболочки, в то время как этот предлагаемый выход находится в коде awk).источник
exit(0)
было очень полезно! Также, для пользователей macos, посмотрите эту суть: хороший портативный awk shebang найти нелегко.