bash read from named pipe, may be OT
I am trying to read from a named pipe using bash, if nothing is in the fifo buffer, repeat the whole process. The -t option of the read comman appears not to work and the following code snippet waits forever for data from the pipe. mkfifo -m 666 ~/fifo while true do while read -t 5 data do echo "data is ($data)" done <~/fifo echo "read again" done and yet, man bash states under the read command the following: -t timeout Cause read to time out and return failure if a complete line of input is not read within timeout seconds. This option has no effect if read is not reading input from the terminal or a pipe. surely, I am not reading from a terminal but I am reading from a pipe, because the type of the file is a pipe # ls -la ~/fifo prw-rw-rw- 1 root root 0 Jan 8 21:44 /root/fifo Installation: SuSE Linux V9.2, Pentium architecture. How do I do it correctly? Thanks Peter
On 08-Jan-06 Peter Sutter wrote:
I am trying to read from a named pipe using bash, if nothing is in the fifo buffer, repeat the whole process. The -t option of the read comman appears not to work and the following code snippet waits forever for data from the pipe.
mkfifo -m 666 ~/fifo while true do while read -t 5 data do echo "data is ($data)" done <~/fifo echo "read again" done
In your line done <~/fifo why is the "<~/fifo" there? Surely this attempts to read indefinitely from ~/fifo. If you leave it out: mkfifo -m 666 ~/fifo while true do while read -t 5 data do echo "data is ($data)" done echo "read again" done it works as you seem to intend! Best wishes, Ted.
and yet, man bash states under the read command the following:
-t timeout Cause read to time out and return failure if a complete line of input is not read within timeout seconds. This option has no effect if read is not reading input from the terminal or a pipe.
surely, I am not reading from a terminal but I am reading from a pipe, because the type of the file is a pipe # ls -la ~/fifo prw-rw-rw- 1 root root 0 Jan 8 21:44 /root/fifo
Installation: SuSE Linux V9.2, Pentium architecture.
How do I do it correctly?
Thanks
Peter
-- Check the headers for your unsubscription address For additional commands send e-mail to suse-linux-e-help@suse.com Also check the archives at http://lists.suse.com Please read the FAQs: suse-linux-e-faq@suse.com
--------------------------------------------------------------------
E-Mail: (Ted Harding)
Thanks Ted and Per, the done <~/fifo is there because I want to read the data from the ~/fifo pipe, not from the terminal; in which case done would be enough. If you send something to ~/fifo like e.g. echo "abcd" >>~/fifo the code will then echo data is(abcd) back, it is doing what it is supposed to do, except it will not honour the timeout but wait indefinitely, thus never execute the remainder of the code. The Idea behind the whole thing is to control asynchronously an important background process that needs root privileges to run. Anybody can send something to the fifo pipe and the script acts on it, without the user needing any special privileges. Peter On Sunday 08 January 2006 22:19, Ted Harding wrote:
On 08-Jan-06 Peter Sutter wrote:
I am trying to read from a named pipe using bash, if nothing is in the fifo buffer, repeat the whole process. The -t option of the read comman appears not to work and the following code snippet waits forever for data from the pipe.
mkfifo -m 666 ~/fifo while true do while read -t 5 data do echo "data is ($data)" done <~/fifo echo "read again" done
In your line
done <~/fifo
why is the "<~/fifo" there? Surely this attempts to read indefinitely from ~/fifo. If you leave it out:
mkfifo -m 666 ~/fifo while true do while read -t 5 data do echo "data is ($data)" done echo "read again" done
it works as you seem to intend!
Best wishes, Ted.
and yet, man bash states under the read command the following:
-t timeout Cause read to time out and return failure if a complete line of input is not read within timeout seconds. This option has no effect if read is not reading input from the terminal or a pipe.
surely, I am not reading from a terminal but I am reading from a pipe, because the type of the file is a pipe # ls -la ~/fifo prw-rw-rw- 1 root root 0 Jan 8 21:44 /root/fifo
Installation: SuSE Linux V9.2, Pentium architecture.
How do I do it correctly?
Thanks
Peter
-- Check the headers for your unsubscription address For additional commands send e-mail to suse-linux-e-help@suse.com Also check the archives at http://lists.suse.com Please read the FAQs: suse-linux-e-faq@suse.com
----------------------------------------------------------------- --- E-Mail: (Ted Harding)
Fax-to-email: +44 (0)870 094 0861 Date: 08-Jan-06 Time: 14:19:40 ------------------------------ XFMail ------------------------------
Thanks to all who responded. mkfifo -m 666 /tmp/fifo # exec - execute commands and open, close, or copy file descriptors # the file descriptor has to be opened with an exec !!! exec 42<> /tmp/fifo while true do while read -t 5 data <&42 do echo "data is ($data)" done echo "read again" done There is nothing magical about the 42, any number will do, but try to avoid stdin, stdout and stderr. The example allows anyone to send something to /tmp/fifo, e.g. echo "command" > /tmp/fifo and the code snipped can act accordingly. Peter
Peter Sutter wrote:
mkfifo -m 666 ~/fifo while true do while read -t 5 data do echo "data is ($data)" done <~/fifo echo "read again" done
[snip]
How do I do it correctly?
There's something funky with doing it inside a shellscript - try doing "read -t5" from the bash prompt - works fine. /Per Jessen, Zürich -- http://www.spamchek.com/ - managed anti-spam and anti-virus solution. Let us analyse your spam- and virus-threat - up to 2 months for free.
Per Jessen wrote:
There's something funky with doing it inside a shellscript - try doing "read -t5" from the bash prompt - works fine.
Yet "read -t5
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 The Sunday 2006-01-08 at 21:46 +0800, Peter Sutter wrote:
while read -t 5 data
and yet, man bash states under the read command the following:
-t timeout Cause read to time out and return failure if a complete line of input is not read within timeout seconds. This option has no effect if read is not reading input from the terminal or a pipe.
I went to "man read", and it says the only valid option is "-r", there is not "-t" option. This is in conflict on what "man bash" says for the "read" entry. - -- Cheers, Carlos Robinson -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (GNU/Linux) Comment: Made with pgp4pine 1.76 iD8DBQFDwu7FtTMYHG2NR9URAocBAJ0TZa5LxW7HxI2Ajq/8bH9PY74S6wCdF+BL VWerPOLyl13oyU75swxHOfU= =bI/g -----END PGP SIGNATURE-----
On Mon, 2006-01-09 at 15:16, Carlos E. R. wrote:
I went to "man read", and it says the only valid option is "-r", there is not "-t" option. This is in conflict on what "man bash" says for the "read" entry. Strange....on my 9.1 system, "man read" says:
read [-ers] [-u fd] [-t timeout] [-a aname] [-p prompt]
[-n nchars] [-d delim] [name ...]
One line is read from the standard input, or from
the file descriptor fd supplied as an argument to
the -u option, and the first word is assigned to
the first name, the second word to the second name,
and so on, with leftover words and their interven
ing separators assigned to the last name. If there
are fewer words read from the input stream than
names, the remaining names are assigned empty val
ues. The characters in IFS are used to split the
line into words. The backslash character (\) may
be used to remove any special meaning for the next
character read and for line continuation. Options,
if supplied, have the following meanings:
I'm just installing 10.0 on another system, so I can't see what "man
read" says there.
--
Jim Cunning
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 The Monday 2006-01-09 at 16:42 -0800, Jim Cunning wrote:
On Mon, 2006-01-09 at 15:16, Carlos E. R. wrote:
I went to "man read", and it says the only valid option is "-r", there is not "-t" option. This is in conflict on what "man bash" says for the "read" entry. Strange....on my 9.1 system, "man read" says:
read [-ers] [-u fd] [-t timeout] [-a aname] [-p prompt] [-n nchars] [-d delim] [name ...] One line is read from the standard input, or from the file descriptor fd supplied as an argument to the -u option, and the first word is assigned to the first name, the second word to the second name, and so on, with leftover words and their interven
It is indeed strange. I have: READ(P) POSIX Programmer's Manual NAME read - read a line from standard input SYNOPSIS read [-r] var... DESCRIPTION The read utility shall read a single line from standard input. ... IEEE/The Open Group 2003 READ(P) I notice now that it is showing read(p). If I specify "man 1 read", then I get: cer@nimrodel:~> man 1 read No manual entry for read in section 1 cer@nimrodel:~> whatis read read (1) [bashbuiltins] - bash built-in commands, see bash(1) read (2) - read from a file descriptor read (n) - Read from a channel read (1p) - read a line from standard input read (3p) - read from a file So the separate man page read(1) has dissapeared, it refers the reader to bash(1) instead, and then read(1p) might be obsolete. That must be why you are getting a different page than me. I have tried your piece of code, and I suppose I get the "wrong" result. Each time I do " echo hello >> fifo" I get: data is (hello) read again but it doesn't timeout and output a list of "read again". It must be considering the named pipe as a file. - -- Cheers, Carlos Robinson -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (GNU/Linux) Comment: Made with pgp4pine 1.76 iD8DBQFDw5PFtTMYHG2NR9URAobBAKCOedNV7DIDPSHpAnf+tB2BbHfK0QCfetLH bvDWzowfZvT0PQahMTNrKKA= =WZd/ -----END PGP SIGNATURE-----
Carlos, On Tuesday 10 January 2006 03:00, Carlos E. R. wrote:
...
It is indeed strange. I have:
READ(P) POSIX Programmer's Manual
...
So the separate man page read(1) has dissapeared, it refers the reader to bash(1) instead, and then read(1p) might be obsolete. That must be why you are getting a different page than me.
What do you get from this command: % apropos read |egrep -i '^read \(1' read (1) [bashbuiltins] - bash built-in commands, see bash(1) read (1p) - read a line from standard input
I have tried your piece of code, and I suppose I get the "wrong" result. Each time I do " echo hello >> fifo" I get:
...
Which shell do you use? BASH also has many operational options, though offhand I don't see one that should effect the read command's ability to effectively implement the semantics of its "-t" option.
...
Randall Schulz
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 The Tuesday 2006-01-10 at 06:51 -0800, Randall R Schulz wrote:
So the separate man page read(1) has dissapeared, it refers the reader to bash(1) instead, and then read(1p) might be obsolete. That must be why you are getting a different page than me.
What do you get from this command:
% apropos read |egrep -i '^read \(1' read (1) [bashbuiltins] - bash built-in commands, see bash(1) read (1p) - read a line from standard input
The same thing. But I think that the OP doesn't, as "man read" produces a diferent page.
I have tried your piece of code, and I suppose I get the "wrong" result. Each time I do " echo hello >> fifo" I get:
...
Which shell do you use? BASH also has many operational options, though offhand I don't see one that should effect the read command's ability to effectively implement the semantics of its "-t" option.
Bash, same as he does. He posted a second script that works as intended. It's an interesting trick he did: it seems he asociates a file descriptor to the named pipe, and uses the descriptor instead. Then the timeout option for "read" works. - -- Cheers, Carlos Robinson -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (GNU/Linux) Comment: Made with pgp4pine 1.76 iD8DBQFDxBEKtTMYHG2NR9URAoduAJ9fVo7cZT3kEdj1paYKJBvu67kstgCfWa2l 4b1DxAbCXTIvlbue5rQ4lPE= =b4sJ -----END PGP SIGNATURE-----
participants (6)
-
Carlos E. R.
-
Jim Cunning
-
Per Jessen
-
Peter Sutter
-
Randall R Schulz
-
Ted.Harding@nessie.mcc.ac.uk