[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
==============================
test1.awk
Description: Text document
test2.awk
Description: Text document
- Certain Use of getline into a Variable from a Pipe in a BEGIN Rule Inhibits Later Non-Special Rule Processing,
Neil R. Ormos <=