Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 如何使bash FIFO等待从另一端读取完毕?_Linux_Bash_Fifo - Fatal编程技术网

Linux 如何使bash FIFO等待从另一端读取完毕?

Linux 如何使bash FIFO等待从另一端读取完毕?,linux,bash,fifo,Linux,Bash,Fifo,我正在编写一个bash脚本,我正在寻找一种可以将命令发送到程序可以读取和执行的文件中的东西。我发现了。从一开始我就开始做实验,我意识到有一个很大的问题:如果输入行大约有100个字符,那么从另一端读取数据失败的几率约为50%。让我举例说明发生了什么 首先,我们需要一个fifo和两个一行程序分别用于服务器和客户端 # creating fifo mkfifo pipe # a-la server while true; do \ echo -n 'Send to client: >

我正在编写一个bash脚本,我正在寻找一种可以将命令发送到程序可以读取和执行的文件中的东西。我发现了。从一开始我就开始做实验,我意识到有一个很大的问题:如果输入行大约有100个字符,那么从另一端读取数据失败的几率约为50%。让我举例说明发生了什么

首先,我们需要一个fifo和两个一行程序分别用于服务器和客户端

# creating fifo
mkfifo pipe

# a-la server
while true; do \
    echo -n 'Send to client: > ';\
    read ;\
    echo "$REPLY" > pipe ;\
    read answer < pipe ;\
    echo "Got answer: $answer" ;\
done

# a-la client
while read < pipe; do \
    echo 'Finished reading.';\
    echo "FROM SERVER: $REPLY" ;\
    echo ACK > pipe ;\
done
在客户机上,只有:

Finished reading.
FROM SERVER: 123
看起来服务器在发送数据后就开始读取数据,所以客户端几乎无法从管道中读取数据。在上面的例子中,他什么都看不懂。这一切也打破了多字节编码的文本

简单地说,就是这样

  • 服务器发送:
    aaaaaa…-这是一条很长的线-…aaaaaa bcbcbc
  • 服务器读取:
    aaaa……abcbbc
  • /实际上与#2/客户端读取服务器尚未读取的内容同时执行:
    aaccb
  • 为了让服务器在尝试从客户端读取“ACK”之前等待,我尝试更改管道的文件权限,使其充当信号量。结果很有趣

    由于我们无法操作读取权限(因为一旦服务器禁止,客户端将无法从管道读取),我们将切换
    -w
    标志

    以下是客户端和服务器的修改版本。注意:在客户端上执行read命令后重定向发生更改

    # a-la server
    chmod 644 pipe ;\
    while true; do \
        echo -n 'Send to client: > ';\
        read ;\
        echo "$REPLY" > pipe ;\
        chmod -w pipe ;\
        until [ -w pipe ]; do \
            echo 'Waiting client to read what we sent' ;\
            sleep 1 ;\
        done ;\
        read answer < pipe ;\
        echo "Got answer: $answer" ;\
    done
    
    # a-la client
    chmod 644 pipe ;\
    set -x ;\
    while read <>pipe; do \
        echo 'Finished reading.' ;\
        chmod u+w pipe ;\
        echo $? ;\
        ls -l pipe &>/dev/null ;\
        echo "FROM SERVER: $REPLY" ;\
        echo ACK > pipe ;\
    done
    
    #a-la服务器
    CHMOD644管\
    虽然真实;做\
    echo-n“发送到客户端:>”\
    阅读\
    回声“$REPLY”>管道\
    chmod-w管\
    直到[-w管道];做\
    echo“等待客户阅读我们发送的内容”\
    睡眠1\
    完成\
    阅读答案<管道\
    echo“得到答案:$answer”\
    完成
    #a-la客户机
    CHMOD644管\
    set-x\
    一边读烟斗;做\
    echo“读完了”\
    chmod u+w管道\
    echo$\
    ls-l管道&>/dev/null\
    echo“来自服务器:$REPLY”\
    回波信号>管道\
    完成
    
    chmod 644
    用于确保管道具有正确的权限,无论您首先启动哪个脚本

    设置-x
    以查看将要出现的乐趣


    由于管道上存在读写锁定,客户端中的重定向更改为
    。我不知道它们是如何工作的,但是在带有
    read命名管道的客户机上读取只是一个单向通信流:任何进程写入的任何内容都会被某个进程从中读取。您有两个进程(服务器和客户端)向其中写入数据,还有两个进程从中读取数据,因此您无法保证哪个进程可以看到哪个输入


    您需要双向通信:您希望您的客户机只看到服务器写入的内容,而您的服务器只看到客户机写入的内容。为此,您需要创建两个命名管道:一个是服务器写入而客户端读取的管道,另一个是客户端写入而服务器读取的管道。

    这是一个很好的建议,我可能会使用它,但我仍然好奇为什么它会等待某个程序检查其权限。
    # a-la server
    chmod 644 pipe ;\
    while true; do \
        echo -n 'Send to client: > ';\
        read ;\
        echo "$REPLY" > pipe ;\
        chmod -w pipe ;\
        until [ -w pipe ]; do \
            echo 'Waiting client to read what we sent' ;\
            sleep 1 ;\
        done ;\
        read answer < pipe ;\
        echo "Got answer: $answer" ;\
    done
    
    # a-la client
    chmod 644 pipe ;\
    set -x ;\
    while read <>pipe; do \
        echo 'Finished reading.' ;\
        chmod u+w pipe ;\
        echo $? ;\
        ls -l pipe &>/dev/null ;\
        echo "FROM SERVER: $REPLY" ;\
        echo ACK > pipe ;\
    done