bash 从两个不同脚本的 fifo 写入和读取

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25900873/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 11:22:37  来源:igfitidea点击:

Write and read from a fifo from two different script

bashfifowriter

提问by Ciccio

I have two bash script. One script write in a fifo. The second one read from the fifo, but AFTER the first one end to write.

我有两个 bash 脚本。一个脚本写在一个先进先出。第二个从fifo读取,但在第一个结束后写入。

But something does not work. I do not understand where the problem is. Here the code.

但是有些东西不起作用。我不明白问题出在哪里。这里是代码。

The first script is (the writer):

第一个脚本是(作者):

#!/bin/bash

fifo_name="myfifo";

# Se non esiste, crea la fifo;
[ -p $fifo_name ] || mkfifo $fifo_name;

exec 3<> $fifo_name;

echo "foo" > $fifo_name;
echo "bar" > $fifo_name;

The second script is (the reader):

第二个脚本是(读者):

#!/bin/bash

fifo_name="myfifo";

while true
do
    if read line <$fifo_name; then
       # if [[ "$line" == 'ar' ]]; then
        #    break
        #fi
        echo $line
    fi
done

Can anyone help me please? Thank you

有人可以帮我吗?谢谢

采纳答案by John1024

Replace the second script with:

将第二个脚本替换为:

#!/bin/bash    
fifo_name="myfifo"
while true
do
    if read line; then
        echo $line
    fi
done <"$fifo_name"

This opens the fifo only once and reads every line from it.

这只会打开 fifo 一次并从中读取每一行。

回答by David C. Rankin

The problem with your setup is that you have fifo creation in the wrong script if you wish to control fifo access to time when the reader is actually running. In order to correct the problem you will need to do something like this:

您设置的问题在于,如果您希望在阅读器实际运行时控制 fifo 访问时间,则您在错误的脚本中创建了 fifo。为了更正问题,您需要执行以下操作:

reader: fifo_read.sh

阅读器:fifo_read.sh

#!/bin/bash

fifo_name="/tmp/myfifo"                         # fifo name

trap "rm -f $fifo_name" EXIT                    # set trap to rm fifo_name at exit

[ -p "$fifo_name" ] || mkfifo "$fifo_name"      # if fifo not found, create

exec 3< $fifo_name                              # redirect fifo_name to fd 3
                                                # (not required, but makes read clearer)
while :; do
    if read -r -u 3 line; then                  # read line from fifo_name
        if [ "$line" = 'quit' ]; then           # if line is quit, quit
            printf "%s: 'quit' command received\n" "$fifo_name"
            break
        fi
        printf "%s: %s\n" "$fifo_name" "$line"  # print line read
    fi
done

exec 3<&-                                       # reset fd 3 redirection

exit 0

writer: fifo_write.sh

作者:fifo_write.sh

#!/bin/bash

fifo_name="/tmp/myfifo"

# Se non esiste, exit :);
[ -p "$fifo_name" ] || {
    printf "\n Error fifo '%s' not found.\n\n" "$fifo_name"
    exit 1
}

[ -n "" ] && 
    printf "%s\n" "" > "$fifo_name" || 
    printf "pid: '%s' writing to fifo\n" "$$" > "$fifo_name"

exit 0

operation: (start reader in 1st terminal)

操作:(在第一个终端启动阅读器)

$ ./fifo_read.sh                         # you can background with & at end

(launch writer in second terminal)

(在第二个终端启动 writer)

$ ./fifo_write.sh "message from writer"  # second terminal
$ ./fifo_write.sh
$ ./fifo_write.sh quit

output in 1st terminal:

第一个终端的输出:

$ ./fifo_read.sh
/tmp/myfifo: message from writer
/tmp/myfifo: pid: '28698' writing to fifo
/tmp/myfifo: 'quit' command received

回答by Julian

The following script should do the job:

以下脚本应该可以完成这项工作:

#!/bin/bash

FIFO="/tmp/fifo"

if [ ! -e "$FIFO" ]; then
        mkfifo "$FIFO"
fi

for script in "$@"; do
        echo $script > $FIFO &
done

while read script; do
        /bin/bash -c $script
done < $FIFO

Given two script a.sh and b.sh where both scripts pass "a" and "b" to stdout, respectively, one will get the following result (given that the script above is called test.sh):

给定两个脚本 a.sh 和 b.sh,其中两个脚本分别将“a”和“b”传递给 stdout,将得到以下结果(假设上面的脚本称为 test.sh):

./test.sh /tmp/a.sh /tmp/b.sh
a
b

Best, Julian

最好的,朱利安