benhoyt / goawk

A POSIX-compliant AWK interpreter written in Go, with CSV support
https://benhoyt.com/writings/goawk/
MIT License
1.95k stars 84 forks source link

close() on pipe command does not return exit status #203

Closed juster closed 1 year ago

juster commented 1 year ago

An undocumented feature of other awks is to have the close() builtin function return the exit status of the process which was opened by the pipe. The close() builtin for goawk always returns -1 for output pipes and always returns 0 for input pipes.

Example

$ goawk 'BEGIN { print|"exit 1"; print close("exit 1") }'
-1
$ goawk 'BEGIN { "exit 1"|getline; print close("exit 1") }'
0

Portability?

Different awks also have various implementations. The same example above was run for ...

  1. the "one-true" Lucent copyright awk
  2. GNU gawk
  3. plan9 from userspace awk
  4. Mac OS awk
Variant Input/Output Pipe Behavior
one-true / mac os both Value is 256 (1 << 8)
gawk both Value is 1
plan9 both Use of the value of close() is illegal

edit: Removed duplicate rows. I also remembered how the wait() result shifts the exit code.

benhoyt commented 1 year ago

Interesting! Linking the GAWK docs on this for reference. For comparison, POSIX just says "If the close was successful, the function shall return zero; otherwise, it shall return non-zero."

juster commented 1 year ago

Ah nice! Those linked docs explain plan9 awk's behavior:

In many older versions of Unix awk, the close() function is actually a statement. (d.c.) It is a syntax error to try and use the return value from close():

It complains about an illegal statement.

But yeah this is definitely an undocumented easter egg!