2014-09-08 24 views
6

Trang web netcat cho biết rằng, trong trường hợp không có tùy chọn -c và -e, một trình bao có thể được phân phát qua nc bằng cách sử dụng các lệnh sau.Thực hiện đường ống Bash

$ rm -f /tmp/f; mkfifo /tmp/f 
$ cat /tmp/f | /bin/sh -i 2>&1 | nc -l 127.0.0.1 1234 > /tmp/f 

Bây giờ, như tôi đã hiểu, cả đọc và viết từ fifos đều chặn hoạt động. Ví dụ: nếu tôi chạy

$ mkfifo foo 
$ cat foo 

bash sẽ chặn, vì không có gì được ghi vào foo. Làm thế nào để các đường ống trong ví dụ từ manpage nc không chặn? Tôi cho rằng tôi hiểu sai đường ống được thực hiện như thế nào.

Trả lời

7

Tất cả các lệnh trong đường ống chạy đồng thời, không tuần tự. Vì vậy, cat /tmp/f thực sự sẽ chặn, nhưng /bin/shnc sẽ vẫn được bắt đầu trong khi điều đó xảy ra. nc sẽ ghi vào FIFO khi một khách hàng kết nối với cổng và gửi một lệnh, và điều này sẽ cho phép cat bỏ chặn.

+0

Ngắn gọn và câu trả lời hay. Cảm ơn! –

3

Ký tự ống trong bash không tạo ra bất cứ thứ gì sau đó kết nối luồng đầu ra của lệnh đầu tiên với luồng đầu vào của dòng thứ hai. echo "123" | cat về cơ bản giống như cat < <(echo 123) (sau này chỉ bắt đầu một vỏ cây mặc dù lần đầu tiên bắt đầu một cái cho mỗi lệnh, nhưng điều này có thể bị bỏ qua ở đây - cộng thêm, đó là bashism và không hoạt động trong sh).

$ mkfifo foo 
$ cat foo 

Thực sự chặn - nhưng không bị đóng băng. Thời điểm bất kỳ chương trình nào khác ghi bất cứ điều gì vào foo, mèo sẽ hiển thị nó.

những gì bạn đang doign trong cuộc gọi netcat của bạn được về cơ bản tạo ra một cicrle: bất cứ điều gì được viết vào FIFO sẽ được hiển thị bằng cat, và, như cat được kết nối với sh gửi đến sau này. sh sau đó sẽ thực thi mã (vì sh chỉ thực hiện bất kỳ điều gì được ghi vào luồng đầu vào của nó) và gửi đầu ra đến nc. nc sẽ gửi cho khách hàng. Mọi thứ mà khách hàng gửi đến nc sẽ được ghi vào FIFO - và vòng kết nối của chúng tôi đã hoàn tất.

Sai lầm bạn đã thực hiện (tôi nghĩ) là giả định quy trình thứ hai của một đường ống chỉ đọc dữ liệu một lần, không liên tục và do đó phải chờ quá trình đầu tiên kết thúc. Điều này là không đúng, bởi vì mọi quá trình trong một đường ống được bắt đầu trong một shubshell, do đó, tất cả họ chạy độc lập của nhau.


Bạn cũng có thể thay đổi thứ tự của tất cả các lệnh trong đường ống. Miễn là người đầu tiên đọc từ FIFO và người cuối cùng viết cho nó (để hoàn thành vòng tròn), nó sẽ hoạt động.

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