[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [bug-gawk] What is wrong with getline from both stdin and a file fro
From: |
Andrew J. Schorr |
Subject: |
Re: [bug-gawk] What is wrong with getline from both stdin and a file from ARGV? |
Date: |
Wed, 28 Nov 2018 13:24:12 -0500 |
User-agent: |
Mutt/1.5.21 (2010-09-15) |
On Wed, Nov 28, 2018 at 11:13:00AM -0600, Peng Yu wrote:
> The second command gives an error. I don't understand why it should
> cause an error, but the other two did not. Could anybody help explain
> this? Thanks.
>
> $ awk -e 'BEGIN { getline < ARGV[1] }' <(printf '%s\n' {a..c})
> printf '%s\n' {a..c}
> $ printf '%s\n' {1..3} | awk -e 'BEGIN { getline; getline < ARGV[1] }'
> <(printf '%s\n' {a..c})
> printf '%s\n' {a..c}
> awk: (FILENAME=/dev/fd/63 FNR=1) warning: close of fd 63
> (`/dev/fd/63') failed (Bad file descriptor)
> $ printf '%s\n' {1..3} | awk -v f=<(printf '%s\n' {a..c}) -e 'BEGIN {
> getline; getline < f; print }'
> printf '%s\n' {a..c}
> a
Because the first getline reads from /dev/fd/63, and then when
you call "getline < ARGV[1]", it accesses /dev/fd/63 again. When the
program exits, it tries to close all open files. First, it closes
the file on the command line /dev/fd/63, and then it closes
fd 63 again because you explicitly opened it using the "getline < ARGV[1]"
syntax. Note that the pipe on stdin is a distraction and has no
impact on the results.
Compare:
bash-4.2$ strace -e open,close awk -e 'BEGIN { getline; print; getline <
ARGV[1]; print }' /etc/passwd
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
close(3) = 0
open("/lib64/libreadline.so.6", O_RDONLY|O_CLOEXEC) = 3
close(3) = 0
open("/lib64/libmpfr.so.4", O_RDONLY|O_CLOEXEC) = 3
close(3) = 0
open("/lib64/libgmp.so.10", O_RDONLY|O_CLOEXEC) = 3
close(3) = 0
open("/lib64/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
close(3) = 0
open("/lib64/libm.so.6", O_RDONLY|O_CLOEXEC) = 3
close(3) = 0
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
close(3) = 0
open("/lib64/libtinfo.so.5", O_RDONLY|O_CLOEXEC) = 3
close(3) = 0
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
close(3) = 0
open("/usr/lib64/gconv/gconv-modules.cache", O_RDONLY) = 3
close(3) = 0
open("/etc/passwd", O_RDONLY) = 3
root:x:0:0:root:/root:/bin/bash
open("/etc/passwd", O_RDONLY) = 4
root:x:0:0:root:/root:/bin/bash
close(3) = 0
close(4) = 0
+++ exited with 0 +++
And now your example:
bash-4.2$ strace -e open,close awk -e 'BEGIN { getline; print; getline <
ARGV[1]; print }' <(printf '%s\n' {a..c})
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
close(3) = 0
open("/lib64/libreadline.so.6", O_RDONLY|O_CLOEXEC) = 3
close(3) = 0
open("/lib64/libmpfr.so.4", O_RDONLY|O_CLOEXEC) = 3
close(3) = 0
open("/lib64/libgmp.so.10", O_RDONLY|O_CLOEXEC) = 3
close(3) = 0
open("/lib64/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
close(3) = 0
open("/lib64/libm.so.6", O_RDONLY|O_CLOEXEC) = 3
close(3) = 0
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
close(3) = 0
open("/lib64/libtinfo.so.5", O_RDONLY|O_CLOEXEC) = 3
close(3) = 0
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
close(3) = 0
open("/usr/lib64/gconv/gconv-modules.cache", O_RDONLY) = 3
close(3) = 0
a
close(63) = 0
a
close(63) = -1 EBADF (Bad file descriptor)
open("/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
close(3) = 0
open("/usr/share/locale/en_US.UTF-8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT
(No such file or directory)
open("/usr/share/locale/en_US.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT
(No such file or directory)
open("/usr/share/locale/en_US/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No
such file or directory)
open("/usr/share/locale/en.UTF-8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT
(No such file or directory)
open("/usr/share/locale/en.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No
such file or directory)
open("/usr/share/locale/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such
file or directory)
open("/usr/share/locale/en_US.UTF-8/LC_MESSAGES/gawk.mo", O_RDONLY) = -1 ENOENT
(No such file or directory)
open("/usr/share/locale/en_US.utf8/LC_MESSAGES/gawk.mo", O_RDONLY) = -1 ENOENT
(No such file or directory)
open("/usr/share/locale/en_US/LC_MESSAGES/gawk.mo", O_RDONLY) = -1 ENOENT (No
such file or directory)
open("/usr/share/locale/en.UTF-8/LC_MESSAGES/gawk.mo", O_RDONLY) = -1 ENOENT
(No such file or directory)
open("/usr/share/locale/en.utf8/LC_MESSAGES/gawk.mo", O_RDONLY) = -1 ENOENT (No
such file or directory)
open("/usr/share/locale/en/LC_MESSAGES/gawk.mo", O_RDONLY) = -1 ENOENT (No such
file or directory)
awk: (FILENAME=/dev/fd/63 FNR=1) warning: close of fd 63 (`/dev/fd/63') failed
(Bad file descriptor)
+++ exited with 0 +++
Regards,
Andy
- [bug-gawk] What is wrong with getline from both stdin and a file from ARGV?, Peng Yu, 2018/11/28
- Re: [bug-gawk] What is wrong with getline from both stdin and a file from ARGV?,
Andrew J. Schorr <=
- Re: [bug-gawk] What is wrong with getline from both stdin and a file from ARGV?, Peng Yu, 2018/11/28
- Re: [bug-gawk] What is wrong with getline from both stdin and a file from ARGV?, Andrew J. Schorr, 2018/11/28
- Re: [bug-gawk] What is wrong with getline from both stdin and a file from ARGV?, Peng Yu, 2018/11/28
- Re: [bug-gawk] What is wrong with getline from both stdin and a file from ARGV?, Andrew J. Schorr, 2018/11/28
- Re: [bug-gawk] What is wrong with getline from both stdin and a file from ARGV?, Peng Yu, 2018/11/28
- Re: [bug-gawk] What is wrong with getline from both stdin and a file from ARGV?, Andrew J. Schorr, 2018/11/29
- Re: [bug-gawk] What is wrong with getline from both stdin and a file from ARGV?, arnold, 2018/11/29