Nhiều đầu vào tiêu chuẩn? Làm sao?


36

Từ bài viết dòng lệnh này :

$ diff <(wget -q -O - URL1) <(wget -q -O - URL2)

Có vẻ như nhiều đầu vào tiêu chuẩn nhưng --- nếu tôi nhớ chính xác khóa học Lập trình Linux của mình --- thì không thể như vậy được. Tôi nghĩ rằng, theo định nghĩa, đầu vào tiêu chuẩn là một luồng.

Có lẽ điều này có zilch để làm với stdin? Ai đó có thể giải thích điều này với tôi; có thể cung cấp các liên kết đến tài liệu.

Phần thưởng: Làm thế nào một tập lệnh sẽ xử lý nhiều luồng này? Nếu ai đó có thể cung cấp một ví dụ Python hoặc Perl, điều đó sẽ rất hữu ích.


1
Câu hỏi hay. Trong trường hợp bạn không biết, có một trang web Hỏi & Đáp unix / linux: unix.stackexchange.com
Matt Ellen


Lưu ý: trong Bash it <(…); trong cú pháp thay thế quá trình Zsh là =(…).
Kamil Maciorowski

Câu trả lời:


27

Đây không phải là nhiều đầu vào tiêu chuẩn. Đây là một chủ nghĩa bash'ism gọi là 'Thay thế quy trình' http://tldp.org/LDP/abs/html/ process-sub.html

Nó tạo ra một tệp giả ( /dev/fd/something) cho mỗi lần thay thế. Nó khá hữu ích. Lệnh chỉ có thể đọc dưới dạng luồng, nghĩa là nó không thể qua lại với fseek. Nó cần phải đọc nó như một luồng byte, giống như một đường ống.

THƯỞNG Trả lời

Bạn không cần phải làm quá nhiều để sử dụng này. Theo như kịch bản của bạn có liên quan, nó nhận được một tên tệp hợp lệ trên dòng lệnh, có thể là open () ed như mọi thứ khác. Như những người khác đã nói, bạn sẽ thấy diff /dev/fd/XX /dev/fd/YY. Nếu bạn thực hiện một stat () trên bất kỳ tệp giả nào trong số này, bạn sẽ thấy đó là một ống có tên và bạn nên xử lý nó bằng ngữ nghĩa ống - cụ thể là không có fseek () hoặc ftell (). Nếu bạn thực hiện kiểm tra stat () để xem rõ ràng nếu đó là một tệp (ví dụ [ -f $1 ]) này sẽ bị hỏng hay không - điều này được thực hiện như một đường ống có tên.


Một tài liệu tham khảo tốt khác để thay thế quy trình bash - wiki.bash-hackers.org/syntax/Exansion/proc_subst
studgeek

Và việc sử dụng đề xuất của tính năng này là gì? Hỗ trợ nó bất cứ khi nào chương trình của bạn có thể hoạt động hợp lý với một luồng thay vì yêu cầu một tệp có quyền truy cập ngẫu nhiên?
masterxilo

7

<(...)không thay thế quá trình trong bash. Đầu ra của quá trình trong các parens được gửi đến một bộ mô tả tệp bổ sung ngoài 3 thông thường và một tên tệp được trả về tương ứng với bộ mô tả tệp đó. Theo cách này, đầu ra của một lệnh có thể được coi là một tên tệp được truyền cho một lệnh khác.


7

Có một stdinvà một stdout cho mỗi quá trình . Chúng thường được kết nối với thiết bị đầu cuối, nhưng chúng có thể được chuyển hướng riêng biệt với nhau.

Trong ví dụ này, có hai wgetquy trình liên quan, mỗi quy trình đều có quy trình riêng stdinstdout. Mỗi wgetquá trình ghi vào -, đó là của nó stdout. Sau đó bash, quá trình thay thế <(...)kết nối stdoutquá trình với một tệp giả duy nhất, từ đó diffcó thể đọc. Lưu ý rằng hai thay thế quá trình mang lại hai tệp giả khác nhau! Vì vậy, diffthấy một cái gì đó như:

diff /dev/fd/XX /dev/fd/YY

nơi stdoutcủa wget -q -O - URL1được kết nối với /dev/fd/XX, và stdoutcủa wget -q -O - URL2để /dev/fd/YY.

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.