Quando você faz:
cmd = "some command"
cmd | getline d2
cmd | getline d2
em awk
, o primeiro getline
obtém a primeira linha (registro) da saída de cmd
( cmd
é iniciado com base nessa primeira getline
) e a segunda obtém a segunda linha . Ao chegar ao final da saída, getline
retorna 0.
No seu caso de cmd = "date -d \"46 years ago\""
, como esse comando produz apenas uma linha, o primeiro getline
retorna essa linha em d2
(e um número positivo), mas o segundo alcança eof
, então retorna 0 e deixa d2
intocado.
Aqui, você precisaria:
cmd | getline d2; close(cmd)
Portanto, cmd
seja executado a cada vez.
Ou armazene a saída de cmd
em um hash para evitar a execução do mesmo comando várias vezes com os mesmos argumentos, como
if (!($2 in cache)) {cmd=...; cmd | getline cache[$2]; close(cmd)}
print cache[$2]
Ainda é uma boa ideia fechar cmd
para evitar que um grande número de descritores de arquivos seja aberto.
Observe a ambiguidade em close(cmd)
quando cmd
é usado para getline < cmd
e cmd | getline
. Fecha o comando cmd
ou o arquivo cmd
ou ambos?
$ cat test.awk
BEGIN{
OFS=","
getline a1 < "uname"
"uname" | getline b1
close("uname")
getline a2 < "uname"
"uname" | getline b2
print a1,b1,a2,b2
}
$ echo test > uname
$ mawk -f test.awk
test,Linux,test,Linux
$ bwk-awk -f test.awk
test,Linux,test,Linux
$ gawk -f test.awk
test,Linux,,Linux
$ busybox awk -f test.awk
test,,test,
( bwk-awk
sendo o mantido por Brian Kernighan (o k
em awk
), o comportamento é similar com implementações awk baseadas nisso como Solaris nawk
ou FreeBSD awk
).
Veja como o busybox awk não permite usar "uname"
como um arquivo e comando com getline
e como close("uname")
não fecha o arquivo uname
em gawk
.
Portanto, é uma boa ideia certificar-se de não usar um arquivo e um comando com o mesmo nome ao mesmo tempo. Você pode adicionar um "\n"
no início ou no final de um comando para tornar improvável que seja confundido com um arquivo .
Como:
awk 'BEGIN {getline foo < $ENVIRON["FILE"]; "uname\n" | getline system}'
evitaria o problema se $FILE
fosse uname
(não se $FILE
fosse uname<newline>
, mas isso fosse menos provável).