2014-09-17 23 views
8

Tôi có hai tập lệnh bash. Một kịch bản viết trong một năm mươi. Người thứ hai đọc từ năm mươi, nhưng SAU là người đầu tiên kết thúc viết.Viết và đọc từ một năm từ hai tập lệnh khác nhau

Nhưng có điều gì đó không hiệu quả. Tôi không hiểu vấn đề ở đâu. Ở đây mã.

Kịch bản thứ nhất là (tác giả):

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

Kịch bản thứ hai là (người đọc):

#!/bin/bash 

fifo_name="myfifo"; 

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

bất cứ ai có thể giúp tôi xin vui lòng? Cảm ơn bạn

+1

gì bạn có nghĩa là "Cái gì đó không hoạt động"? – choroba

+0

Không kịch bản nào cho tôi bất kỳ lỗi nào. Nhưng khi tôi chạy kịch bản thứ hai không có gì được in trên màn hình. Vì vậy, tôi không hiểu nếu tôi sai khi tôi viết trong nămo hoặc khi tôi đọc từ fifo – Ciccio

Trả lời

6

Thay thế kịch bản thứ hai với:

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

này mở ra fifo chỉ một lần và đọc tất cả các dòng từ nó.

+0

Doe không làm việc với tôi: (Khi tôi chạy kịch bản thứ hai không có gì xảy ra và cũng kịch bản không chấm dứt :(Tôi phải bấm CTRL + C – Ciccio

+0

@Ciccio Vâng, tập lệnh không chấm dứt vì nó đang đợi một thứ gì đó để đọc từ năm mươi. Trong khi chờ đợi, hãy chạy tập lệnh khác viết cho nămo. – John1024

+0

@Ciccio Ngoài ra, tập lệnh đầu tiên không chấm dứt cho đến khi một số tiến trình đã đọc từ nămo. Khi kịch bản thứ hai kết thúc đọc những gì kịch bản đầu tiên đã viết, kịch bản đầu tiên sẽ chấm dứt. Kịch bản thứ hai, vì vòng lặp 'while true', tiếp tục chờ đợi thêm đầu vào. – John1024

2

Sự cố với thiết lập của bạn là bạn đã tạo nămo trong tập lệnh sai nếu bạn muốn kiểm soát quyền truy cập của nămo vào thời điểm người đọc thực sự đang chạy. Để khắc phục sự cố bạn sẽ cần phải làm một cái gì đó như thế này:

đọc: 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 

nhà văn: 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 

hoạt động: (trình đọc đầu tiên trong thiết bị đầu cuối thứ nhất)

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

(ra mắt nhà văn trong nhà ga thứ hai)

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

đầu ra trong 1 thiết bị đầu cuối:

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

+1 Bạn giải quyết vấn đề ở bàn tay, nhưng như một lưu ý: Sẽ không 'đọc-r dòng <$ fifo_name' được tốt hơn? Vì bây giờ, kịch bản * reader * sẽ đi vào vòng lặp chuyên sâu của CPU sau thông báo đầu tiên. Cũng vậy với cách tiếp cận [được đưa ra bởi John1024] (http://stackoverflow.com/a/25901141/1968548). – Runium

+0

Cảm ơn. Như đã lưu ý trong bình luận, việc chuyển hướng liên tục sang fd3 là không cần thiết, mục đích chỉ là giữ cho kịch bản logic sạch sẽ làm cho nó rõ ràng rằng nămo đã được chuyển hướng và được sử dụng để đọc nguồn cấp dữ liệu. (nó cũng đã cho cơ hội để hiển thị đọc từ một mô tả tập tin tùy chỉnh - đó là cần thiết nếu đọc từ nhiều fds trong một vòng lặp duy nhất (ví dụ: fd3 & stdin) .Tôi không thấy bất kỳ lý do nào cách tiếp cận của bạn sẽ không hoạt động như nhau cho nó một shot. –

0

Các kịch bản sau đây cần thực hiện công việc:

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

Do hai tập lệnh a.sh và b.sh ở đâu cả hai kịch bản vượt qua "a" và "b" để stdout, tương ứng, người ta sẽ có được kết quả như sau (cho rằng kịch bản trên được gọi là test.sh):

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

nhất, Julian

Các vấn đề liên quan