2015-02-14 23 views
7

Tôi đang cố tạo kết nối liên tục bằng bash. Mở terminal 1, tôi giữ một netcat chạy như một máy chủ:Kết nối liên tục trong tập lệnh Bash

$ nc -vlkp 3000 
Listening on [0.0.0.0] (family 0, port 3000) 

trên terminal 2, tôi tạo ra một fifo và giữ một con mèo:

$ mkfifo fifo 
$ cat > fifo 

trên thiết bị đầu cuối 3, tôi làm cho fifo như một đầu vào cho một netcat khách hàng:

$ cat fifo | nc -v localhost 3000 
Connection to localhost 3000 port [tcp/*] succeeded! 

Mở terminal 4, tôi gửi cho bất cứ điều gì tôi muốn:

$ echo command1 > fifo 
$ echo command2 > fifo 
$ echo command3 > fifo 

Trở lại với terminal 1, tôi thấy các lệnh được nhận:

$ nc -vlkp 3000 
Listening on [0.0.0.0] (family 0, port 3000) 
Connection from [127.0.0.1] port 3000 [tcp/*] accepted (family 2, sport 41722) 
command1 
command2 
command3 

Vì vậy, mọi thứ hoạt động. Nhưng khi tôi đưa rằng trong một kịch bản (tôi gọi fifo.sh đó), bash là không thể viết vào FIFO:

Mở terminal 1, cùng một máy chủ nghe:

$ nc -vlkp 3000 
Listening on [0.0.0.0] (family 0, port 3000) 

Mở terminal 2, tôi chạy kịch bản:

#!/bin/bash 

rm -f fifo 
mkfifo fifo 
cat > fifo & 
pid1=$! 
cat fifo | nc -v localhost 3000 & 
pid2=$! 

echo sending... 
echo comando1 > fifo 
echo comando2 > fifo 
echo comando3 > fifo 

kill -9 $pid1 $pid2 

sản lượng trong terminal 2 là:

$ ./fifo.sh 
Connection to localhost 3000 port [tcp/*] succeeded! 
sending... 

Mở terminal 1 tôi chỉ thấy connec sự. Không có lệnh:

$ nc -vlkp 3000 
Listening on [0.0.0.0] (family 0, port 3000) 
Connection from [127.0.0.1] port 3000 [tcp/*] accepted (family 2, sport 42191) 
Connection closed, listening again. 

Bất kỳ ý tưởng nào về lý do tại sao nó chỉ hoạt động tương tác? Hoặc có cách nào khác để tạo kết nối liên tục chỉ sử dụng Bash không? Tôi không muốn đi cho mong đợi bởi vì tôi có một kịch bản Bash lớn hơn mà làm một số công việc sau khi gửi lệnh1, và command2 phụ thuộc vào đầu ra command1, vv

Cảm ơn bạn!

+1

Xin chào và chào mừng bạn đến với Stack Overflow! Đây là câu hỏi mới bắt đầu tốt nhất mà tôi từng thấy. – l0b0

Trả lời

2

Khi quá trình được bắt đầu trong nền trong tập lệnh, đầu vào tiêu chuẩn được chuyển hướng từ /dev/null. Điều này có nghĩa là lệnh cat đầu tiên sẽ đọc và phát ra EOF ngay sau khi nó thực thi, điều này sẽ khiến cho netcat thoát ngay lập tức sau khi bắt đầu, vì vậy đầu ra sau trong tập lệnh sẽ không bao giờ xuất hiện trong nămo, vì không có người nghe đang hoạt động tại thời điểm đó.

Trong trường hợp này, khi cat > fifo được đánh giá, trình bao sẽ hỗ trợ quy trình con, chuyển hướng nhập chuẩn từ /dev/null và cố gắng mở fifo để viết. Đứa trẻ vẫn còn trong cuộc gọi chặn open vào lúc này. Lưu ý rằng cat không được thực hiện cho đến sau khi hoàn tất cuộc gọi open.

Tiếp theo, cat fifo | nc -v localhost 3000 được sinh ra. cat mở fifo để đọc, cho phép chặn open từ đứa trẻ đầu tiên hoàn thành và cat đầu tiên để thực thi.

Đầu tiên cat kế thừa bộ mô tả tệp của phụ huynh, vì vậy đầu vào tiêu chuẩn của nó được gắn vào /dev/null và do đó đọc và phát ra ngay EOF.Số thứ hai cat đọc số EOF và chuyển số đó vào đầu vào chuẩn của nc, khiến cho netcat thoát.

Đến thời điểm báo cáo echo được đánh giá, các quy trình được xác định bằng $pid1$pid2 hoàn tất. Vì không còn là người nghe trên fifo, nên echo đầu tiên sẽ chặn vĩnh viễn.


Tôi không có bản sửa lỗi thuần túy, nhưng bạn có thể sử dụng chương trình bên ngoài như perl để mở trình giữ chỗ giữ chỗ fifo thay vì sử dụng chuyển hướng vỏ. Ngoài ra, xin lưu ý rằng có một cuộc đua với số nc bắt đầu sau câu lệnh echo (trong đó kill xảy ra trước khi netcat có cơ hội xử lý đầu vào/đầu ra gửi), vì vậy tại đây tôi đã thêm trễ sau biểu thức cat | nc. Có gần như chắc chắn là một giải pháp tốt hơn trên mạng, nhưng đây là những gì tôi đã đưa ra:

#!/bin/bash 

rm -f fifo 
mkfifo fifo 
perl -e 'open(my $fh, ">", "fifo"); sleep 3600 while 1' & 
pid1=$! 
cat fifo | nc -v localhost 3000 & 
pid2=$! 

sleep 2 

echo sending... 
echo comando1 > fifo 
echo comando2 > fifo 
echo comando3 > fifo 

kill -9 $pid1 $pid2 

Hy vọng điều này sẽ giúp ích cho bạn!

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