bug-gawk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: no exit status available when a command doesn't exist or fails in pi


From: Ed Morton
Subject: Re: no exit status available when a command doesn't exist or fails in pipe to grep
Date: Thu, 9 Sep 2021 14:38:58 -0500
User-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Thunderbird/78.13.0



On 9/9/2021 1:49 PM, Neil R. Ormos wrote:
Ed Morton wrote:
Neil R. Ormos wrote:
Ed Morton wrote:
arnold@skeeve.com wrote:
"Andrew J. Schorr" wrote:
So gawk forces the return code to 0 in POSIX
mode in almost all cases.
[...] And as I pointed out earlier, different
awks do different things anyway, so there's no
reliable portable way to deal with the status
from close().
That's fine of course but why not just do in
POSIX mode the same thing that gawk does in
non-POSIX mode since it'd apparently still be
POSIX compliant either way and would be more
useful?
How would that be compliant with the POSIX
requirement that
| If the close was successful, the
| function shall return zero; otherwise,
| it shall return non-zero.
... ?
How does a return code from the command used
with the pipeline affect whether the close()
was successful?
It depends what "successful" means. Imagine you
try to close a door that was never opened:
   a) if "success" means the door is closed then
   the result is "success",
   b) If "success" means the action you took
   caused the door to close then the result is
   "failure"
Since POSIX doesn't define "succesful" in the
context of calling close() it can mean whichever
we want it to mean
No. [*]

and in the above example I'd hope we'd go with
"b" and get results from calling close() like:
   0 (success) = the action we took caused the
   command to close, or
   N (failure) = or our attempt to close it
   failed for reason N (which includes why it was
   already closed if that was the case)
since that would be much more useful than just 0
if the command is closed or N if our attempt to
close it failed and lose the information about
why it was already closed before we tried to
close it if that was the case.
Even adopting that definition of "success" would
still not get you the return code from the
command, because the effect "our attempt to
close() [the command]" appears to be invariant
regardless of whether the piped command has
failed.
It will get us the return code of the command if we allow it to. Here's what the GNU manual says:

   In gawk, starting with version 4.2, when closing a pipe or coprocess
   (input or output), the return value is the exit status of the command

All I'm suggesting is that gawk do the same thing whether it's in POSIX mode or not and I think that's reasonable since POSIX doesn't define "success"
Consider these scripts and results:
I did but I'm not sure what I'm supposed to get out of them. Change each `close(...)` to `print close(...)` and they do exactly what I want/expect. In the 2nd example where you say "the following close did not fail" - yes it did fail because a return code of 0 is success and anything else is failure and it is returning non-0:

   gawk 'BEGIN{c1="date -d 2021-13-01";      \
     r1=( c1 | getline rec1); print r1, rec1;  \
     c2=c1;                                    \
     r2=( c2 | getline rec2); print r2, rec2;  \
     c3=c1; print "close returned", close(c1); \
     r3=( c3 | getline rec3); print r3, rec3;}'
   date: invalid date ‘2021-13-01’
   0
   0
   close returned 1
   date: invalid date ‘2021-13-01’
   0

Note that the `1` returned from `close()` is the same exit status we'd get if we just called that date command directly:

   $ date -d 2021-13-01; echo "$?"
   date: invalid date ‘2021-13-01’
   1

and if we used some non-existent command:

   $ garbage
   -bash: garbage: command not found
   $ echo $?
   127

we again get the correct, failure exit status:

   gawk 'BEGIN{c1="garbage";      \
     r1=( c1 | getline rec1); print r1, rec1;  \
     c2=c1;                                    \
     r2=( c2 | getline rec2); print r2, rec2;  \
     c3=c1; print "close returned", close(c1); \
     r3=( c3 | getline rec3); print r3, rec3;}'
   sh: garbage: command not found
   0
   0
   close returned 127
   sh: garbage: command not found
   0

Regards,

    Ed.


============================================================

  gawk 'BEGIN{c1="date -d 2021-01-01";      \
  r1=( c1 | getline rec1); print r1, rec1;  \
  c2=c1;                                    \
  r2=( c2 | getline rec2); print r2, rec2;  \
  c3=c1; close(c1);                         \
  r3=( c3 | getline rec3); print r3, rec3;}' |& nl -v 10
10 1 Fri Jan 1 00:00:00 CST 2021
      11 0
      12 1 Fri Jan  1 00:00:00 CST 2021

============================================================

  gawk 'BEGIN{c1="date -d 2021-13-01";      \
  r1=( c1 | getline rec1); print r1, rec1;  \
  c2=c1;                                    \
  r2=( c2 | getline rec2); print r2, rec2;  \
  c3=c1; close(c1);                         \
  r3=( c3 | getline rec3); print r3, rec3;}' |& nl -v 20
20 date: invalid date '2021-13-01'
      21 0
      22 0
      23 date: invalid date '2021-13-01'
      24 0

============================================================

In the first script, the date command produces the
expected result (output line 10), a second attempt
to pipe the same command without having first
called close() produces nothing for getline to
read (line 11) because date was not re-run, and a
third attempt after close() again produces the
expected result (line 12) and shows that the call
to close() produced the documented effect of
allowing a subsequent pipe of the identical
command to run.

In the second script, in which the date command
was contrived to fail, attempting to pipe a second
time without calling close did not re-run date
(line 22), but the third attempt to pipe the
command did re-run date (line 23), showing that
the immediately preceding close() worked.  Even
though the first date command failed, the
following close did not fail, but instead close()
produced the documented effect, just as it did in
the first script where date succeeded, of allowing
a subsequent pipe of the identical command to run.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]