Cách xử lý bash xử lý >>


9

Trong khi thử nghiệm chuyển hướng đầu ra và thay thế quá trình, tôi đã vấp phải lệnh sau và kết quả đầu ra của nó:

    me @ elem: ~ $ echo foo >> (mèo); thanh vang
    quán ba
    tôi @ elem: ~ $ foo

(Vâng, dòng mới trống ở cuối là có chủ ý.)

Vì vậy, bash thanh echo, in dấu nhắc thông thường của tôi, foo của echo, một dòng mới và để con trỏ của tôi ở đó. Nếu tôi nhấn enter lần nữa, nó sẽ in lời nhắc của tôi trên một dòng mới và để con trỏ theo sau nó (như mong đợi khi có ai đó nhấn enter trên một dòng lệnh trống).

Tôi đang mong đợi nó viết foo cho một người mô tả tập tin, con mèo đọc nó và tiếng vang của nó, thanh tiếng vang thứ hai, rồi quay lại dấu nhắc lệnh. Nhưng đó rõ ràng không phải là trường hợp.

Ai đó có thể vui lòng giải thích những gì đang xảy ra?


Tôi muốn đề nghị tìm kiếm câu trả lời về điều này: unix.stackexchange.com/questions/182800/ Khăn Nó giải thích chuyển hướng kép và sẽ giải thích lý do tại sao bạn kết thúc với các kết quả khác nhau. Cả Muru và Michael Hormers.
Không có thời gian

Đối với một câu hỏi xử lý rõ ràng lý do tại sao đầu ra của sự thay thế quá trình xuất hiện sau lời nhắc (và trong một số trường hợp hoàn toàn không xuất hiện) trong một số phiên bản của vỏ Bourne Again, hãy xem unix.stackexchange.com/questions/471987 .
JdeBP

Câu trả lời:


9

Bạn có thể thấy foohiển thị trước bar, sau barhoặc thậm chí sau lời nhắc, tùy thuộc vào thời gian. Thêm một chút chậm trễ để có được thời gian nhất quán:

$ echo foo > >(sleep 1; cat); echo bar; sleep 2 
bar
foo
$

barxuất hiện ngay lập tức, foosau một giây, sau đó nhắc tiếp theo sau một giây nữa.

Điều gì đang xảy ra là bash thực hiện các thay thế quá trình trong nền.

  1. Quá trình bash chính bắt đầu một lớp con để thực thi sleep 1; catvà thiết lập một đường ống đến nó.
  2. Quá trình bash chính thực hiện echo foo. Vì điều này không lấp đầy bộ đệm của đường ống, echolệnh sẽ chấm dứt mà không chặn.
  3. Quá trình bash chính thực hiện echo bar.
  4. Quá trình bash chính khởi chạy lệnh sleep 2.
  5. Trong khi đó, subshell đang khởi chạy lệnh sleep 1.
  6. Sau khoảng 1 giây, sleep 1trả về trong quy trình con. Quá trình con tiến hành thực hiện cat.
  7. cat sao chép đầu vào của nó thành đầu ra của nó (được hiển thị trên màn hình) và trả về.
  8. Subshell đã hoàn thành công việc của nó, nó thoát.
  9. Sau một giây, sleep 2trở lại. Quá trình shell chính kết thúc thực thi và bạn có thể thấy dấu nhắc tiếp theo.

3

Bạn không cần thay thế quá trình để có được hiệu ứng đó. Thử cái này:

( echo foo | cat & )

Bạn sẽ nhận được nhiều kết quả tương tự (không có bar; tôi sẽ để nó như một bài tập) và với cùng một lý do. Trong cả hai trường hợp, catđược bắt đầu như một nhiệm vụ nền. Trong dòng của tôi ở đây, đó là rõ ràng. Trong trường hợp thay thế quy trình, nó cũng rõ ràng - đó là một quy trình riêng biệt được đính kèm với một bộ mô tả tệp tên - nhưng có lẽ nó không rõ ràng.

Quá trình con không nhất thiết phải chấm dứt trước khi bashin dấu nhắc tiếp theo. Và vì đầu ra của nó được đệm, nó không xuất ra bất cứ thứ gì cho đến khi nó kết thúc. Tại thời điểm đó, bash vừa được in $trên stderr, và bây giờ quá trình nền thoát ra sau khi in foovà một dòng mới.

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.