Write and read from a fifo from two different scri

2020-06-12 03:32发布

问题:

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.

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

回答1:

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.



回答2:

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:

reader: 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

#!/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 "$1" ] && 
    printf "%s\n" "$1" > "$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)

$ ./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


回答3:

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):

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

Best, Julian



标签: bash fifo writer