Trong zsh, sự khác biệt giữa mèo <(cat) vs cat | mèo vs mèo = (mèo)?


18

Tôi đã mong đợi cat <(cat)cat | catlàm điều tương tự: sao chép các dòng từ stdin sang stdout. Sự hiểu biết của tôi là cả hai sẽ thực hiện một catlớp con, chuyển hướng catthiết bị đầu cuối của lớp con sang một ống có tên tạm thời, và sau đó thực hiện một cái khác cattrong lớp vỏ hiện tại với stdin được chuyển hướng đến đường ống.

Thay vào đó, cat <(cat)cho phép tôi gõ tại thiết bị đầu cuối của mình, nhưng không có dòng đầu vào nào bị sao chép và ^Dkhông báo hiệu EOF; cat | cathoạt động như mong đợi mặc dù.

Như một thử nghiệm tiếp theo, tôi đã kiểm tra xem cat =(cat)có gặp khó khăn tương tự không cat <(cat), nhưng nó hoạt động như tôi mong đợi: tất cả các stdin cho đến khi ^Dđược sao chép vào thiết bị xuất chuẩn trong một lần.

Bất cứ ai có thể giúp tôi hiểu những gì zsh đang làm dưới mui xe?

Câu trả lời:


23
  1. a | bconnect STDOUTtừ aSTDINtừ bchỉ bằng cách sử dụng dup/dup2. Cả hai lệnh được thực hiện song song.

  2. a =(b)thay thế đối số abằng một tên tệp tạm thời. bsẽ được thực thi trước khi atập tin tạm thời cần được tạo trước khi nó có thể được chuyển đếna

  3. a <(b)thay thế đối số abằng một ống có tên. abchạy song song. Đây là lúc nó hơi phức tạp một chút:

    bở chế độ nền và không thể đọc từ thiết bị đầu cuối. Bạn có thể tự kiểm tra bằng cách sử dụng strace -p $PIDđể đính kèm vào quy trình con mèo thứ hai của bạn để xem quy trình.

    atrong khi đó cố gắng đọc từ đường ống được đặt tên nhưng không thể đọc bất cứ điều gì mà bkhông thể đọc.

    • Điều này có nghĩa là về cơ bản bạn có một bế tắc nơi acố gắng đọc từ bnhưng bkhông thể đọc từ STDINvà không thể viết choa

Thông tin thêm về quá trình nền và thiết bị đầu cuối từ man bash :

Để tạo điều kiện cho việc thực hiện giao diện người dùng để kiểm soát công việc, hệ điều hành duy trì khái niệm ID nhóm quy trình đầu cuối hiện tại . Các thành viên của nhóm quy trình này (các quy trình có ID nhóm quy trình bằng với ID nhóm quy trình đầu cuối hiện tại) nhận các tín hiệu do bàn phím tạo ra như SIGINT . Các quy trình này được cho là ở phía trước . Lý lịchcác quy trình là những quy trình có ID nhóm quy trình khác với các thiết bị đầu cuối; các quá trình như vậy là miễn dịch với các tín hiệu do bàn phím tạo ra. Chỉ các quá trình tiền cảnh mới được phép đọc từ hoặc, nếu người dùng chỉ định với stty tostop, hãy ghi vào thiết bị đầu cuối. Các quá trình nền cố đọc từ (ghi vào khi stty tostop có hiệu lực), thiết bị đầu cuối được gửi tín hiệu SIGTTIN (SIGTTOU) bởi trình điều khiển đầu cuối của kernel, trừ khi bị bắt, đình chỉ quá trình.


Tuyệt vời, cảm ơn bạn - điều này đã làm sáng tỏ rất nhiều!
Alan O'Donnell

1
Lưu ý khi không tương tác, zsh chuyển hướng đầu vào tiêu chuẩn của các lệnh nền (bao gồm cả các lệnh trong <(cmd)) để /dev/nullhành vi khác nhau ( zsh -c 'cat <(cat)'trả về ngay lập tức và không xuất ra bất cứ điều gì).
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.