quá trình nền ống đầu vào


14

nếu tôi muốn hiển thị "aaa" trên màn hình:

(1)$: echo aaa | cat                 ... works OK
(2)$: echo aaa | ( cat )             ... works OK
(3)$: echo aaa | ( cat & )           ... NOT working
(4)$: ( echo aaa & ) | cat           ... works OK 
(5)$: echo aaa | ( cat <&0 & )       ... works ok in BASH (but not in SH)
(6)$: echo aaa | ( cat <&3 & ) 3<&0  ... works ok in BASH and SH

sự kết hợp từ (3) và (4) -> quá trình tách rời vẫn có đầu ra được kết nối có thể được kiểm soát, sử dụng, chuyển hướng ..., nhưng không được nhập!

Câu hỏi của tôi là: có ai hiểu tại sao và làm thế nào dòng (5) hoạt động không ???

... "<& 0" là viết tắt của "0 <& 0", tại sao chuyển hướng 0 đến 0 là giải pháp và điều gì thực sự xảy ra đằng sau với đầu vào của quá trình tách rời. Subshell không phải là vấn đề, sử dụng dấu ngoặc nhọn {...} thay vì (...) cung cấp kết quả tương tự.

... Và câu hỏi 2: có giải pháp nào tốt hơn cho "đưa đầu vào cho quá trình tách rời" so với dòng (6).

Câu trả lời:


12

Có, theo yêu cầu của POSIX , các lệnh bắt đầu trong nền &có chuyển hướng đầu vào tiêu chuẩn của chúng /dev/null.

Và thực sự

{ cmd <&3 3<&- & } 3<&0

là cách rõ ràng nhất để làm việc xung quanh nó.

Không rõ lý do tại sao bạn muốn chạy một phần của đường ống trong nền.


Lý do là để có được PID của một lệnh cụ thể bên trong chuỗi ống (cmd1 | {cmd2 &; pid2 = $!;} | cmd3 ..., vì vậy / dev / null == & 0 là tiêu chuẩn cho các quy tắc BG, bạn có biết tại sao không "0 <& 0" hoạt động trong bash ... và nó có an toàn không?
Asain Kujovic

3
@OmerMerdan POSIX cho biết Trong mọi trường hợp, việc chuyển hướng rõ ràng của đầu vào tiêu chuẩn sẽ ghi đè lên hoạt động này , điều này mâu thuẫn với những gì nó đã nói ở trên, vì vậy tôi tin rằng bashdiễn giải nó (và nghe có vẻ như một cách giải thích hợp lý) là hủy bỏ /dev/nullchuyển hướng. Bây giờ, không có nhiều vỏ làm như vậy. Ash và pdksh không.
Stéphane Chazelas

Tại sao nó là 3<&-phần cần thiết và nó có an toàn để sử dụng nó không (nó sẽ không đóng đường ống trước khi đọc toàn bộ đầu vào ir)?
mvorisek

1
@Mvorisek, fd 3 đó chỉ được sử dụng tạm thời để khôi phục stdin gốc. Chúng tôi đóng nó như cmdkhông cần nó. Chúng tôi đóng nó sau khi chúng tôi đã nhân đôi nó lên fd 0 ( <&3viết tắt của 0<&3).
Stéphane Chazelas

1
@Mvorisek, nohupcũng chuyển hướng stdin thành / dev / null, vì vậy bạn cần : { nohup sh -c 'cmd <&3 3<&-' & } 3<&0. Hoặc(trap '' HUP; cmd <&3 3<&- > nohup.out 2>&1 &) 3<&0
Stéphane Chazelas
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.