Я сделал 2 параллельных процесса, которые взаимодействуют с именованным каналом. Я заметил странное поведение: за каждой записью должно следовать чтение или наоборот! Если мы нарушаем правило, программа зависает, а если мы завершаем ее с помощью Ctrl+C, дочерний элемент все равно зависает, что означает, что он просто больше не может повторно читать.
Мой пример:
#!/bin/bash
shopt -u failglob
shopt -s extglob nullglob dotglob
function london (){
local message answer fifo id return exitcode
fifo=fifo_$RANDOM.$RANDOM.$RANDOM.$$
mkfifo ${fifo}
#trap 'rm -rf "$fifo"' EXIT
( berlin $fifo ) &
id=$!
echo "parent id: $$, child id: $id"
message='Greetings from London!(1)'
echo "$message" > $fifo
echo "1. parent sent it's 1st message"
#*****write-to-write error!*****#
message='Greetings from London!(2)'
#read -r answer < $fifo
echo "$message" > $fifo
echo "2. parent sent it's 2nd message"
wait
rm -rf $fifo
}
function berlin (){
local message answer fifo
fifo=$1
read -r answer < $fifo
echo 'Berlin says:> '"$answer"
#*****read-to-read error!*****#
#echo 'next' > $fifo
read -r answer < $fifo
echo 'Berlin says:> '"$answer"
}
london
Под точками, где я вставил сообщения «запись для записи» или «чтение для чтения», есть 2 строки с комментариями, которые решают проблему, заставляя меня думать, что вышеуказанное правило таинственным образом выполняется !!! Есть идеи, что происходит?
Вот результат:
parent id: 4921, child id: 4923
1. parent sent it's 1st message
2. parent sent it's 2nd message
Berlin says:> Greetings from London!(1)
Спасибо!
Думаю, теперь все понятно и сжато в одну фразу: "держите трубу открытой со стороны читателя".
Предположим теперь, что я хочу добавить второй дескриптор входного файла для «некоторых» моих команд внутри цикла; как я могу это сделать? Вот моя новая берлинская функция:
function berlin (){
local message answer fifo
fifo=$1
while true; do
read -r answer
echo 'Berlin says:> '"$answer"
#this fails!
read -r -p "reading from fd0: " <&0
if [[ $answer = 'quit' ]]; then
break
fi
done < "$fifo" 3>"$fifo"
}
Как видите, мы используем файловый дескриптор 3 для канала, но когда мы пытаемся читать из fd 0, мы на самом деле читаем из fd 3! Есть ли способ добиться этого?