#unix #awk #command-line-interface
#unix #awk #интерфейс командной строки
Вопрос:
Поэтому, когда я запускаю это на mac:
awk 'END { for (name in ENVIRON) {
print "key: "name; }
}' >> app-deployment.yaml
awk просто зависает. Если я изменю его, чтобы просто печатать /dev/null
, как это
awk 'END { for (name in ENVIRON) {
print "key: "name; }
}' < /dev/null
Все работает нормально. Я делаю что-то не так с моим перенаправлением? Есть ли что-то еще, что я здесь делаю неправильно?
Комментарии:
1. «чтение из» (
<
) ! = «запись в» (>>
).
Ответ №1:
Измените END
на BEGIN
, чтобы иметь возможность работать без какого-либо ввода:
awk 'BEGIN { for (name in ENVIRON) {
print "key: "name; }
}' >> app-deployment.yaml
Ответ №2:
Если программа awk состоит только из действий с шаблоном
BEGIN
, аBEGIN
действие не содержитgetline
функции, awk завершит работу, не считывая свои входные данные, когда выполняется последний оператор в последнемBEGIN
действии. Если программа awk состоит только из действий с шаблономEND
или только действий с шаблонамиBEGIN
иEND
, входные данные должны быть прочитаны до выполнения инструкций вEND
действиях.источник: стандарт POSIX awk
Итак, вкратце:
awk 'BEGIN{ action-without-getline }'
: awk завершается без обработки каких-либо входных файловawk 'BEGIN{ action-with-getline }'
: awk завершается после обработки входных файловawk 'END{ action }'
: awk завершается после обработки входных файловawk 'BEGIN{action}END{ action }'
: awk завершается после обработки входных файловawk 'BEGIN{action; exit}END{ action }'
: awk завершается без обработки каких-либо входных файлов
Но что, если входные файлы не указаны:
Выполнение программы awk должно начинаться с первого выполнения действий, связанных со всеми
BEGIN
шаблонами, в том порядке, в котором они встречаются в программе. Затем каждый операнд файла (или стандартный ввод, если файлы не были указаны) должен обрабатываться по очереди…источник: стандарт POSIX awk
Так что это просто означает, что
$ awk 'END{action}'
не зависает, но ожидает ввода от /dev/stdin
Ответ №3:
Анализ кода OP 1:
awk 'END { for (name in ENVIRON) {
print "key: "name; }
}' >> app-deployment.yaml
Не имеет никакого Input_file, переданного awk
и END
блокируемого в любом awk
коде, требует передачи любого Input_file, он зависает там, поскольку НЕ может его найти.
Анализ Code2 OP:
awk 'END { for (name in ENVIRON) {
print "key: "name; }
}' < /dev/null
Теперь вы передаете /dev/null
в качестве входных данных awk
(хотя у него НЕ будет никакого содержимого для чтения, awk
но все же ему передается ввод), поэтому, согласно правилу, как только Input_file завершает обработку END
блочных процессов, в данном случае, поскольку содержимого там нет, поэтому END
должна произойти печать разделов операторов.
Чтобы заставить awk
код работать без прохождения Input_file
пути: на случай, если кто-то захочет awk
работать без Input_file
использования только BEGIN
раздела, который, согласно man awk
странице, будет выполнен до Input_file
обработки, поэтому даже если вы НЕ передаете какой-либо Input_file, он НЕ будет ждать его присутствия, и как только BEGIN
раздел будет выполнен, он выйдет из программы.