bug-gawk
[Top][All Lists]
Advanced

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

Certain Use of getline into a Variable from a Pipe in a BEGIN Rule Inhib


From: Neil R. Ormos
Subject: Certain Use of getline into a Variable from a Pipe in a BEGIN Rule Inhibits Later Non-Special Rule Processing
Date: Mon, 21 Apr 2025 20:06:59 -0500 (CDT)
User-agent: Alpine 2.20 (DEB 67 2015-01-07)

Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -g -O2 -DNDEBUG
uname output: Linux host 6.1.0-33-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.133-1 
(2025-04-10) x86_64 GNU/Linux
Machine Type: x86_64-pc-linux-gnu

Gawk Version: 5.3.2

Attestation 1:
        I have read 
https://www.gnu.org/software/gawk/manual/html_node/Bugs.html.
        Yes

Attestation 2:
        I have not modified the sources before building gawk.
        True

Description:

I am using the feature described in the manual, Sec. 4.10.6, "Using getline 
into a Variable from a Pipe," in a BEGIN rule.

When the command is a particular call to ssh--see test1.awk and its example 
run--the non-special STDIN rule processing loop is inhibited, as though an exit 
statement had been encountered in the BEGIN rule.

The test1.awk program has, in addition to the BEGIN rule, a single non-special 
rule with an empty pattern and a simple action that is supposed to print each 
input record.  When test1.awk is run with a record is supplied on STDIN, the 
non-special rule does not print anything.  The profiler shows no counts for the 
non-special rule.

When a slightly different command is used, also involving a call to ssh--see 
test2.awk and its example run--the STDIN pattern/action processing loop works 
as expected.  The record supplied on STDIN is printed, and the profiler shows 
that the non-special rule runs.  (The test2.awk program has the same 
non-special rule as is contained in test1.awk.)

The point of the ssh calls in the BEGIN rules is to run, on the ssh target 
host, /something/ embedded within the piped command.  For the purpose of this 
report, the /something/ consists of two successive calls to date(1) as a 
trivial example that produces recognizable output, and the ssh target host is 
localhost.  (On the test machine, ssh is set up to use public key 
authentication.)

The difference between the calls to ssh in the BEGIN rules of the two programs 
is that:

* in test1.awk, which behaves unexpectedly, the embedded /something/
  is the /command/ argument to ssh; whereas

* in test2.awk, which behaves as expected, the embedded /something/
  command is piped to ssh, and the /command/ argument to ssh is a
  shell.  (Omitting to name a shell as the /command/ argument to ssh
  also results in the expected behavior, but ssh runs the user's
  default shell as a login shell which prints startup messages.)

In both cases, the output lines from the date commands on the ssh target are 
received by getline and look to be as expected.  It does not appear that ssh 
hangs in either case.  And in both cases, the result of close() on the original 
command string is 0.

Whatever might be different about the two calls to ssh, and whatever the fates 
of those calls, once the calls return, shouldn't the non-special STDIN rule be 
executed unless an error is reported?

Apologies in advance if this is really a user error.


Repeat-By:

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

cat -v test1.awk
BEGIN{
  cmdx="ssh -4 localhost 'date; date'";
  while ( fres = ( cmdx | getline rec ) ) {
    print rec;
    }; # while
  fres=close(cmdx);
  print "result of close(): ", fres;
  }; # BEGIN

# Main loop

{
  print NR, $0;
  };

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

cat -v test2.awk
BEGIN{
  cmdx="echo 'date; date' | ssh -4 localhost dash";
  while ( fres = ( cmdx | getline rec ) ) {
    print rec;
    }; # while
  fres=close(cmdx);
  print "result of close(): ", fres;
  }; # BEGIN

# Main loop

{
  print NR, $0;
  };

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

diff test1.awk test2.awk
2c2
<   cmdx="ssh -4 localhost 'date; date'";
---
>   cmdx="echo 'date; date' | ssh -4 localhost dash";

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

# SAMPLE RUN OF test1.awk

> echo "a-line-that-should-be-received-on-STDIN" | ~/.local/bin/gawk-5.3.2 -f 
> test1.awk
Mon Apr 21 17:54:04 CDT 2025
Mon Apr 21 17:54:04 CDT 2025
result of close():  0

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

# SAMPLE RUN OF test2.awk
# Note the fourth line of output from test2.awk that is missing from output of 
test1.awk.

> echo "a-line-that-should-be-received-on-STDIN" | ~/.local/bin/gawk-5.3.2 -f 
> test2.awk
Mon Apr 21 17:54:04 CDT 2025
Mon Apr 21 17:54:04 CDT 2025
result of close():  0
1 a-line-that-should-be-received-on-STDIN

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

Attachment: test1.awk
Description: Text document

Attachment: test2.awk
Description: Text document


reply via email to

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