Bash script with non-blocking read

后端 未结 3 1283
说谎
说谎 2021-02-15 16:29

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         


        
相关标签:
3条回答
  • 2021-02-15 16:38

    You can use stty to set a timeout. IIRC its something like

    stty -F $pipe -icanon time 0
    
    0 讨论(0)
  • 2021-02-15 16:41

    Just put the reading cycle into background (add & after done)?

    0 讨论(0)
  • 2021-02-15 16:50

    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
    
    0 讨论(0)
提交回复
热议问题