I want to send some data to a root process with a named pipe. Here is the script and it works great:
#!/bin/sh
pipe=/tmp/ntp
if [[ ! -p $pipe ]]; then
mknod -m 666 $pipe p
fi
while true
do
if read line <$pipe; then
/root/netman/extra/bin/ntpclient -s -h $line > $pipe 2>&1
fi
done
I actually have several script like this one. I would like to enclose all of them in a single script. The problem is that execution blocks on the first "read" and I cannot execute multiple "reads" in a single process. Isn't there anything I can do? Is it possible to have a "non-blocking" bash read?
bash [filename] runs the commands saved in a file. $@ refers to all of a shell script's command-line arguments. $1 , $2 , etc., refer to the first command-line argument, the second command-line argument, etc. Place variables in quotes if the values might have spaces in them.
$() means: "first evaluate this, and then evaluate the rest of the line". Ex : echo $(pwd)/myFile.txt. will be interpreted as echo /my/path/myFile.txt. On the other hand ${} expands a variable.
And the != operator means 'is not equal to', so [ $? != 0 ] is checking to see if $? is not equal to zero. Putting all that together, the above code checks to see if the grep found a match or not.
Bash uses whitespace to determine where words begin and end. The first word is the command name and additional words become arguments to that command.
Bash's read embedded command has a -t parameter to set a timeout:
-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.
This should help you solve this issue.
Edit:
There are some restrictions for this solution to work as the man page indicates: This option has no effect if read is not reading input from the terminal or a pipe.
So if I create a pipe in /tmp:
mknod /tmp/pipe p
Reading directly from the pipe is not working:
$ read -t 1 </tmp/pipe ; echo $?
Hangs forever.
$ cat /tmp/pipe | ( read -t 1 ; echo $? )
1
It is working but cat is not exiting.
A solution is to assign the pipe to a file descriptor:
$ exec 7<>/tmp/pipe
And then read from this file descriptor either using redirection:
$ read -t 1 <&7 ; echo $?
1
Or the -u
option of read
:
$ read -t 1 -u 7 ; echo $?
1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With