2014-09-17 5 views
8

У меня есть два сценария bash. Один скрипт напишите в fifo. Второй читается из fifo, но ПОСЛЕ первого конца для записи.Запись и чтение из fifo из двух разных сценариев

Но что-то не работает. Я не понимаю, где проблема. Вот код.

Первый сценарий (автор):

#!/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; 

Второй сценарий (читатель):

#!/bin/bash 

fifo_name="myfifo"; 

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

Может кто-нибудь мне помочь, пожалуйста? Спасибо

+1

Что делать вы подразумеваете под «Что-то не работает»? – choroba

+0

Никакой скрипт не дает мне никакой ошибки. Но когда я запускаю второй скрипт, на экране ничего не печатается. Поэтому я не понимаю, ошибаюсь ли я, когда пишу в fifo или когда читаю с fifo. – Ciccio

ответ

6

Заменить второй сценарий с:

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

Это открывает ФИФО только один раз и читает каждую строку из него.

+0

Doe не работает со мной :(Когда я запускаю второй скрипт, ничего не происходит, а также скрипт не заканчивается :(Я должен нажать CTRL + C – Ciccio

+0

@Ciccio Да, сценарий не заканчивается, потому что он ждет чего-то, что прочитает из fifo. Пока он ждет, запустите другой скрипт, который пишет в fifo. – John1024

+0

@Ciccio Кроме того, первый скрипт не заканчивается до тех пор, пока какой-то процесс не прочитает из fifo. Когда второй скрипт завершит чтение того, что написал первый скрипт, первый скрипт завершится. Второй скрипт из-за цикла while while продолжает ждать ввода большего количества. – John1024

2

Проблема с вашей настройкой заключается в том, что у вас есть создание fifo в неправильном скрипте, если вы хотите контролировать доступ к файлу fifo во время работы программы. Для того, чтобы исправить эту проблему вам нужно будет сделать что-то вроде этого:

читателя: 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 

Автор: 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 

операции: (запуск считывателя в 1-м терминале)

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

(запуск писатель во втором терминале)

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

выход в 1-ом терминале:

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

+1 Вы обращаетесь к проблеме под рукой, но как примечание: не будет ли 'read -r line <$ fifo_name' be лучше? Как теперь, скрипт * reader * войдет в интенсивный цикл процессора после первого сообщения. То же самое касается подхода [дано John1024] (http://stackoverflow.com/a/25901141/1968548). – Runium

+0

Спасибо. Как отмечено в комментарии, постоянное перенаправление на fd3 необязательно, целью было просто сохранить чистоту логики сценария, чтобы было очевидно, что fifo перенаправляется и используется для чтения чтения. (это также дало возможность показать чтение из пользовательского дескриптора файла, что необходимо при чтении из нескольких fds в одном цикле (например, fd3 и stdin). Я не вижу причин, по которым ваш подход не будет работать одинаково Отбросьте это. –

0

Следующий скрипт должен делать эту работу:

#!/bin/bash 

FIFO="/tmp/fifo" 

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

for script in "[email protected]"; do 
     echo $script > $FIFO & 
done 

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

Учитывая два сценария a.sh и b.sh, где оба скрипта проходят «а» и «б» на стандартный вывод, соответственно, один получит следующий результат (учитывая, что выше сценарий называется test.sh):

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

Best, Джулиан

 Смежные вопросы

  • Нет связанных вопросов^_^