So when I run this on a mac:
awk 'END { for (name in ENVIRON) {
print "key: "name; }
}' >> app-deployment.yaml
awk just freezes. If I change it to just print to /dev/null
like this
awk 'END { for (name in ENVIRON) {
print "key: "name; }
}' < /dev/null
It works fine. Am I doing something wrong with my redirection? Is there something else I'm doing wrong here?
Change END
to BEGIN
to be able to work without any input:
awk 'BEGIN { for (name in ENVIRON) {
print "key: "name; }
}' >> app-deployment.yaml
If an awk program consists of only actions with the pattern BEGIN
, and the BEGIN
action contains no getline
function, awk shall exit without reading its input when the last statement in the last BEGIN
action is executed. If an awk program consists of only actions with the pattern END
or only actions with the patterns BEGIN
and END
, the input shall be read before the statements in the END
actions are executed.
source: POSIX awk Standard
So in short:
awk 'BEGIN{ action-without-getline }'
: awk exits without processing any input files
awk 'BEGIN{ action-with-getline }'
: awk exits after processing the input files
awk 'END{ action }'
: awk exits after processing the input files
awk 'BEGIN{action}END{ action }'
: awk exits after processing the input files
awk 'BEGIN{action; exit}END{ action }'
: awk exits without processing any input files
But what if there are no input files specified:
Execution of the awk program shall start by first executing the actions associated with all BEGIN
patterns in the order they occur in the program. Then each file operand (or standard input if no files were specified) shall be processed in turn ...
source: POSIX awk Standard
So this just means that
$ awk 'END{action}'
will not hang, but awaits input from /dev/stdin
OP's Code1 analysis:
awk 'END { for (name in ENVIRON) {
print "key: "name; }
}' >> app-deployment.yaml
Doesn't have any Input_file passed to awk
and END
block in any awk
code requires any Input_file to be passed,it hangs there since it is NOT able to find one.
OP's Code2 analysis:
awk 'END { for (name in ENVIRON) {
print "key: "name; }
}' < /dev/null
Now you are passing /dev/null
as an Input to awk
(though it will NOT have any contents to be read by awk
but still it has a Input passed to it), so as per rule once Input_file is done processing END
block processes, in this case since NO contents are there so END
section printing of statements should happen.
To make awk
code work without passing an Input_file
way: In case anyone wants to awk
to work without Input_file
use only BEGIN
section, which as per man awk
page will be executed before Input_file
gets processed so even you are NOT passing any Input_file it will NOT wait for its presence and once BEGIN
section is executed it will come out of program.