Một dòng có 2 tệp tmp (không phải những gì bạn muốn) sẽ là:
foo | bar > file1.txt && baz | quux > file2.txt && diff file1.txt file2.txt
Với bash , bạn có thể thử mặc dù:
diff <(foo | bar) <(baz | quux)
foo | bar | diff - <(baz | quux) # or only use process substitution once
Phiên bản thứ 2 sẽ nhắc rõ hơn cho bạn biết đầu vào nào, bằng cách hiển thị
-- /dev/stdin
so với ++ /dev/fd/63
hoặc một cái gì đó, thay vì hai fds được đánh số.
Thậm chí một ống có tên sẽ không xuất hiện trong hệ thống tệp, ít nhất là trên các hệ điều hành nơi bash có thể thực hiện thay thế quy trình bằng cách sử dụng tên tệp như /dev/fd/63
để lấy tên tệp mà lệnh có thể mở và đọc từ để thực sự đọc từ bộ mô tả tệp đã mở mà bash đã đặt lên trước khi thực hiện lệnh. (tức là bash sử dụng pipe(2)
trước ngã ba, và sau đó dup2
để chuyển hướng từ đầu ra của quux
một bộ mô tả tệp đầu vào cho diff
, trên fd 63.)
Trên một hệ thống không có "phép thuật" /dev/fd
hoặc /proc/self/fd
, bash có thể sử dụng các đường dẫn có tên để thực hiện thay thế quy trình, nhưng ít nhất nó sẽ tự quản lý chúng, không giống như các tệp tạm thời và dữ liệu của bạn sẽ không được ghi vào hệ thống tệp.
Bạn có thể kiểm tra cách bash thực hiện quá trình thay thế bằng echo <(true)
cách in tên tệp thay vì đọc từ nó. Nó in /dev/fd/63
trên một hệ thống Linux điển hình. Hoặc để biết thêm chi tiết về chính xác những gì hệ thống gọi bash sử dụng, lệnh này trên hệ thống Linux sẽ theo dõi các cuộc gọi hệ thống mô tả tệp và tệp
strace -f -efile,desc,clone,execve bash -c '/bin/true | diff -u - <(/bin/true)'
Nếu không có bash, bạn có thể tạo ra một đường ống có tên . Sử dụng -
để nói diff
để đọc một đầu vào từ STDIN và sử dụng đường ống có tên như khác:
mkfifo file1_pipe.txt
foo|bar > file1_pipe.txt && baz | quux | diff file1_pipe.txt - && rm file1_pipe.txt
Lưu ý rằng bạn chỉ có thể chuyển một đầu ra thành nhiều đầu vào bằng lệnh tee:
ls *.txt | tee /dev/tty txtlist.txt
Lệnh trên hiển thị đầu ra của ls * .txt đến thiết bị đầu cuối và xuất nó ra tệp văn bản txtlist.txt.
Nhưng với quá trình thay thế, bạn có thể sử dụng tee
để cung cấp cùng một dữ liệu vào nhiều đường ống:
cat *.txt | tee >(foo | bar > result1.txt) >(baz | quux > result2.txt) | foobar
mkfifo a; cmd >a& cmd2|diff a -; rm a