Hallo,
why does the gawk-function close return -1 ?
the file sortiert.txt was created and exists (with the sorted print-string).
The source Code:
BEGIN{
print "b\n\na\nx\n9" | "sort > sortiert.txt"
error = close ("sort > sortiert.txt")
print error
if (error) {print "close error"} else {print "close ok"}
}
in this example close returns 0 (as expected):
BEGIN{
print "I am the content" > "foo.txt"
error= close ("foo.txt")
if (error) {print "close error"} else {print "close ok"}
}
example 3: close returns 0 (as expected):
BEGIN{
"date" | getline
if (!NF) {exit -1;}
print "Date: ", $0
error=close("date")
if (error) {print "close error"} else {print "close ok"}
}
rovf
April 15, 2016, 1:31am
2
You need to close the writing side of the pipe, not the reading side. From the gawk manual:
======
For example, if you open a pipe with this: "sort -r names" | getline foo
then you must close it with this:
close("sort -r names")
hallo,
My example1 is from this nawk-site:
www . staff.science.uu.nl/~oostr102/docs/nawk/nawk_39.html
Trim the spaces in the url (i am not allowed to post links)
if you open a pipe with this:
print $1 | "sort -r > names.sorted"
then you must close it with this:
close("sort -r > names.sorted")
print pipes the data to the shell-command.
wilmaed:
Hallo,
why does the gawk-function close return -1 ?
the file sortiert.txt was created and exists (with the sorted print-string).
The source Code:
BEGIN{
print "b\n\na\nx\n9" | "sort > sortiert.txt"
error = close ("sort > sortiert.txt")
print error
if (error) {print "close error"} else {print "close ok"}
}
in this example close returns 0 (as expected):
BEGIN{
print "I am the content" > "foo.txt"
error= close ("foo.txt")
if (error) {print "close error"} else {print "close ok"}
}
example 3: close returns 0 (as expected):
BEGIN{
"date" | getline
if (!NF) {exit -1;}
print "Date: ", $0
error=close("date")
if (error) {print "close error"} else {print "close ok"}
}
What output do you get from the following command sequence?:
date
printf "b\n\na\nx\n9\n" | sort > sortiert.txt
printf 'exit code is %d\n' $?
ls -l sortiert.txt
id
Hi,
my cygwin (GNU Awk 4.1.3) output:
wilma@windows10 /
$ unlink sortiert.txt
$ date
Fr, 15. Apr 2016 09:12:41
wilma@windows10 /
$ printf "b\n\na\nx\n9\n" | sort > sortiert.txt
wilma@windows10 /
$ printf 'exit code is %d\n' $?
exit code is 0
wilma@windows10 /
$ ls -l sortiert.txt
-rw----r--+ 1 wilma Kein 9 15. Apr 09:12 sortiert.txt
wilma@windows10 /
$ id
uid=197609(wilma) gid=197121(Kein) Gruppen=197121(Kein),545(Benutzer),4(INTERAKTIV),66049(KONSOLENANMELDUNG),11(Authentifizierte Benutzer),15(Diese Organisation),113(Lokales Konto),66048(LOKAL),262154(NTLM-Authentifizierung),401408(Mittlere Verbindlichkeitsstufe)
wilma@windows10 /
$ more sortiert.txt
9
a
b
x
RudiC
April 15, 2016, 3:32am
6
wilmaed:
Hallo,
why does the gawk-function close return -1 ?
the file sortiert.txt was created and exists (with the sorted print-string).
The source Code:
BEGIN{
print "b\n\na\nx\n9" | "sort > sortiert.txt"
error = close ("sort > sortiert.txt")
print error
if (error) {print "close error"} else {print "close ok"}
}
.
.
.
"sort > sortiert.txt"
is not open. The target for your print has two spaces in front of the redirection.
rovf
April 15, 2016, 4:42am
8
This is fine, because it closes the *writer*. You are closing the *reader*.
RudiC
April 15, 2016, 5:23am
9
Sorry, No. You have to close any file (pipe/redirection/command), be it target for a print
or source of a getline
, in order to avoid exceeding awk
's open file limit (1021 for my nawk
, I guess OPEN_MAX - stdin, stdout, stderr).
rovf
April 15, 2016, 11:50am
10
Yes, but only the writing end of the pipe, because if you close it, the reading end will close it by itself. At least this is what the example in th gawk docs say.
If you want to explicitly close both ends, you would need two close statements, but I guess the second one (for the right side of the pipe) will fail.
rovf:
Yes, but only the writing end of the pipe, because if you close it, the reading end will close it by itself. At least this is what the example in th gawk docs say.
If you want to explicitly close both ends, you would need two close statements, but I guess the second one (for the right side of the pipe) will fail.
No. An awk
pipeline does not work that way.
Suppose that we have a file named 123
that contains:
1
2
3
With that file, and an executable shell script named tester
containing:
#!/bin/ksh
awk '
BEGIN { cmd = "cat 123"
for(i = 1; i <= 4; i++) {
if((rc = (cmd | getline)) == 1) {
print $0 > ("no_input_close" i)
close("no_input_close" i)
} else if(rc == 0)
print "EOF in 1st loop on read " i
else print "ERROR in 1st loop on read " i
}
close(cmd)
for(i = 1; i <= 4; i++) {
if((rc = (cmd | getline)) == 1) {
close(cmd)
print $0 > ("with_input_close" i)
close("with_input_close" i)
} else if(rc == 0)
print "EOF in 2nd loop on read " i
else print "ERROR in 2nd loop on read " i
}
}'
Running the script produces the output:
EOF in 1st loop on read 4
and the directory contents are:
-rw-r--r-- 1 dwc staff 6 Apr 15 14:20 123
-rw-r--r-- 1 dwc staff 2 Apr 15 14:48 no_input_close1
-rw-r--r-- 1 dwc staff 2 Apr 15 14:48 no_input_close2
-rw-r--r-- 1 dwc staff 2 Apr 15 14:48 no_input_close3
-rwxr-xr-x 1 dwc staff 540 Apr 15 14:47 tester
-rw-r--r-- 1 dwc staff 2 Apr 15 14:48 with_input_close1
-rw-r--r-- 1 dwc staff 2 Apr 15 14:48 with_input_close2
-rw-r--r-- 1 dwc staff 2 Apr 15 14:48 with_input_close3
-rw-r--r-- 1 dwc staff 2 Apr 15 14:48 with_input_close4
and the contents of the files produced by the awk
program are:
$ for i in *input*
> do echo "*** $i"
> cat $i
> done
*** no_input_close1
1
*** no_input_close2
2
*** no_input_close3
3
*** with_input_close1
1
*** with_input_close2
1
*** with_input_close3
1
*** with_input_close4
1
$
If the input file had been closed (as you suggested) when the output files ar closed in the 1st awk for
loop, there would be four no_input_closeX
instead of three and their contents would be the same as the with_input_closeX
files. But, instead we see that even though the output files are closed in the 1st loop, the input command pipeline remains open and each getline
in the 1st for
loop gets a subsequent input line from the cat
command instead of restarting at the 1st line as n the 2nd for
loop where both the input and output streams are closed each time through the loop.
The only files that awk
automatically closes are input files named as operands that are closed when EOF is reached.
2 Likes