Я хотел бы выполнить сценарий gawk с --re-interval
использованием shebang. «Наивный» подход
#!/usr/bin/gawk --re-interval -f
... awk script goes here
не работает, поскольку gawk вызывается с первым аргументом "--re-interval -f"
(не разделенным вокруг пробелов), который он не понимает. Есть ли обходной путь для этого?
Конечно, вы можете либо не вызывать gawk напрямую, а обернуть его в сценарий оболочки, который разделяет первый аргумент, либо создать сценарий оболочки, который затем вызывает gawk и помещает сценарий в другой файл, но мне было интересно, есть ли способ сделать это в одном файле.
Поведение строк shebang отличается от системы к системе - по крайней мере, в Cygwin он не разделяет аргументы пробелами. Меня просто волнует, как это сделать в системе, которая ведет себя подобным образом; сценарий не предназначен для переносимости.
--re-interval
он больше не нужен (см. [ Gnu.org/software/gawk/manual/… ).Ответы:
Мне кажется, это работает с (g) awk.
Обратите внимание на
#!
запуски/bin/sh
, поэтому этот сценарий сначала интерпретируется как сценарий оболочки.Сначала просто попробовала
"exec" "/usr/bin/gawk" "--re-interval" "-f" "$0" "$@"
, но awk обработал это как команду и безоговорочно распечатал каждую строку ввода. Вот почему я вставляю ...arbitrary_long_name==0
он должен постоянно давать сбой. Вы можете заменить его какой-нибудь тарабарщиной строкой. По сути, я искал в awk ложное условие, которое не повлияло бы отрицательно на сценарий оболочки.В сценарии оболочки
arbitrary_long_name==0
определяет вызываемую переменнуюarbitrary_long_name
и устанавливает для нее значение=0
.источник
bash
POSIX или будет ли он работать с любым POSIXsh
? И я неawk
часто использую , поэтому я не уверен, что мой трюк со второй строкой - хороший способ заставитьawk
игнорировать строку.arbitrary_long_name
не конфликтует с переменной, используемой в реальной программе awk, я не вижу никаких проблем. Что-то мне не хватает?#!/bin/sh -
вместо,#!/bin/sh
чтобы защитить сценарий от возможного неправильного поведения опасным образом, если он вызывается с нулевым аргументом, который имеет-
первый символ. Это может произойти случайно в языках программирования, таких как C, где легко случайно испортить, забыв передать имя вызванной программы как часть массива аргументов вexecve
и аналогичные функции, и если люди обычно забывают защитить от этого, это также может в конечном итоге становятся последним шагом в злонамеренной уязвимости, которая позволяет злоумышленнику получить интерактивную оболочку.Строка shebang никогда не указывалась как часть POSIX, SUS, LSB или какой-либо другой спецификации. AFAIK, это даже не было должным образом задокументировано.
Существует общее мнение о том, что он делает: брать все, что находится между «
!
и»\n
и «exec
оно». Предполагается, что все между «!
и»\n
- это полный абсолютный путь к интерпретатору. Нет единого мнения о том, что произойдет, если он содержит пробелы.К счастью, 1 и 4 вроде бы вымерли, но 3. довольно широко распространен, поэтому вы просто не можете полагаться на возможность передать более одного аргумента.
А поскольку расположение команд также не указано в стандарте POSIX или SUS, вы обычно использовать , что один аргумент, передавая исполняемый файл имя , чтобы
env
таким образом , что он может определить местоположение исполняемого файла; например:[Очевидно, что это все еще предполагает определенный путь
env
, но существует только очень мало систем, в которых он находится/bin
, так что это в целом безопасно. Расположениеenv
гораздо более стандартизировано, чем расположениеgawk
или, что еще хуже, что-то вродеpython
илиruby
илиspidermonkey
.]Это означает , что вы не можете использовать какие - либо аргументы вообще .
источник
-S
переключатель, который здесь помогает, но его нет в моем Linuxenv
, и я подозреваю, что он недоступен и в gygwin. @hstoerr, другие пользователи с другими ситуациями могут читать ваши вопросы позже, поэтому в целом переносимые ответы предпочтительнее, даже если вам сейчас не требуется переносимость.#!/bin/sh
и/usr/bin/env gawk --re-interval -f my-script.awk
. Это правильно?#!
сама по себе не переносима. Например, Windows вообще не распознает это соглашение «изначально». Традиционно в Unix для этого требуется использование одного аргумента#!/usr/bin/awk -f
.#!/usr/bin/env ruby
или ему подобных.Хотя это не совсем переносимо, начиная с coreutils 8.30 и в соответствии с его документацией вы сможете использовать:
Так дано:
ты получишь:
и если вам интересно
showargs
:Оригинальный ответ здесь .
источник
Я столкнулся с той же проблемой, но без видимого решения из-за того, как пробелы обрабатываются в shebang (по крайней мере, в Linux).
Однако вы можете передать несколько параметров в shebang, если они являются короткими и могут быть объединены (способ GNU).
Например, у вас не может быть
но ты можешь иметь
Очевидно, это работает только тогда, когда варианты имеют короткие эквиваленты и не принимают аргументов.
источник
В Cygwin и Linux все, что находится после пути к shebang, анализируется в программе как один аргумент.
Можно обойти это, используя другой
awk
скрипт внутри shebang:Это выполнит
{system("/usr/bin/gawk --re-interval -f " FILENAME); exit}
в awk.И это будет выполняться
/usr/bin/gawk --re-interval -f path/to/your/script.awk
в вашей системной оболочке.источник
Приведенный выше трюк с оболочкой shebang более портативен, чем
/usr/bin/env
.источник
python
, но этот вопрос оawk
.В руководстве gawk (http://www.gnu.org/manual/gawk/gawk.html) в конце раздела 1.14 отмечается, что вы должны использовать только один аргумент при запуске gawk из строки shebang. В нем говорится, что ОС будет рассматривать все, что находится после пути к gawk, как один аргумент. Может, есть еще способ указать
--re-interval
опцию? Возможно, ваш сценарий может ссылаться на вашу оболочку в строке shebang, запускатьсяgawk
как команда и включать текст вашего сценария как «здесь документ».источник
gawk
, но вы все равно можете передать что-то через stderr (то есть перенаправить stdout на stderr, прежде чем подключать к этому скрипту). Я никогда не пробовал этого, но если первый процесс ничего не генерирует на stderr, это может сработать. Вы также можете создать именованный канал ( linuxjournal.com/content/using- named- pipes-fifos-bash ), если хотите убедиться, что ничто другое его не использует.Почему бы не использовать
bash
иgawk
себя, чтобы пропустить мимо притон, прочитал сценарий, и передать его в виде файла на втором экземпляреgawk [--with-whatever-number-of-params-you-need]
?(- то же самое, естественно, можно сделать, например,
sed
илиtail
, но я думаю, что есть какая-то красота, зависящая только отbash
иgawk
;)источник
Просто для развлечения: существует следующее довольно странное решение, которое перенаправляет стандартный ввод и программу через файловые дескрипторы 3 и 4. Вы также можете создать временный файл для сценария.
Одно раздражает в этом: оболочка расширяет переменные в скрипте, поэтому вы должны заключать в кавычки каждый $ (как это сделано во второй строке скрипта) и, возможно, даже больше.
источник
Для переносимого решения используйте
awk
вместоgawk
, вызывайте стандартную оболочку BOURNE (/bin/sh
) с вашим shebang и вызывайтеawk
напрямую, передавая программу в командной строке как здесь документ, а не через stdin:Примечание: без
-f
аргументовawk
. Это оставляетstdin
доступным дляawk
чтения входные данные. Предполагая, что выgawk
установили и на своемPATH
, это достигает всего, что, как я думаю, вы пытались сделать с вашим исходным примером (при условии, что вы хотите, чтобы содержимое файла было сценарием awk, а не вводом, что, я думаю, ваш подход shebang рассматривал бы его как ).источник