awk зависает когда я направляю в файл - PullRequest
1 голос
/ 10 апреля 2019

Итак, когда я запускаю это на 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

Работает нормально. Я делаю что-то не так с моим перенаправлением? Есть ли что-то еще, что я делаю здесь не так?

Ответы [ 3 ]

3 голосов
/ 10 апреля 2019

Измените END на BEGIN, чтобы иметь возможность работать без ввода:

awk 'BEGIN { for (name in ENVIRON) {
  print "key: "name; }
}' >> app-deployment.yaml
2 голосов
/ 10 апреля 2019

Если программа awk состоит только из действий с шаблоном BEGIN, а действие BEGIN не содержит функции getline, awk завершит работу, не прочитав свой ввод, когда последний оператор в последнем действии BEGIN казнены. Если программа awk состоит только из действий с шаблоном END или только действий с шаблонами BEGIN и END, входные данные должны быть прочитаны перед выполнением операторов в действиях END.

источник: POSIX awk Standard

Итак, вкратце:

  • 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 Standard

Так что это просто означает, что

$ awk 'END{action}'

не будет зависать, но ожидает ввода от /dev/stdin

1 голос
/ 10 апреля 2019

Анализ кода1 OP:

awk 'END { for (name in ENVIRON) {
  print "key: "name; }
}' >> app-deployment.yaml

Нет ни одного Input_file, переданного в блок awk, и END в любом коде awk требует передачи любого Input_file, он зависает там, так как не может найти его.



Анализ кода2 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 он выйдет из программы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...