Sự khác biệt chính là <(
... )
, được gọi là "thay thế quy trình", được dịch bởi trình bao thành tên tệp được chuyển làm đối số thông thường cho lệnh; nó không gửi bất cứ thứ gì vào đầu vào tiêu chuẩn của lệnh. Điều này có nghĩa rằng nó không thể được sử dụng trực tiếp với các lệnh như tr
mà không mất một đối số filename:
$ tr a-z A-Z <(echo hello)
usage: tr [-Ccsu] string1 string2
tr [-Ccu] -d string1
tr [-Ccu] -s string1
tr [-Ccu] -ds string1 string2
Tuy nhiên, bạn luôn có thể đặt <
khác ở phía trước của <(
... )
để biến nó thành một chuyển hướng đầu vào thay vì:
$ tr a-z A-Z < <(echo hello)
HELLO
Và bởi vì nó tạo ra một tên tập tin, bạn có thể sử dụng thay thế tiến trình với các lệnh mà mất hơn một đối số file:
$ diff -u <(echo $'foo\nbar\nbaz') <(echo $'foo\nbaz\nzoo')
--- /dev/fd/63 2016-07-15 14:48:52.000000000 -0400
+++ /dev/fd/62 2016-07-15 14:48:52.000000000 -0400
@@ -1,3 +1,3 @@
foo
-bar
baz
+zoo
Sự khác biệt quan trọng khác là một ống tạo subshells mà không thể có tác dụng phụ trong môi trường mẹ:
$ echo hello | read x
$ echo $x
# nothing - x is not set
Nhưng với quá trình thay thế, chỉ có quá trình bên trong ngoặc là trong một subshell; lệnh xung quanh vẫn có thể có tác dụng phụ:
$ read x < <(echo hello)
$ echo $x
hello
Đáng nói rằng bạn cũng có thể viết thành một quá trình với >(
... )
, mặc dù có những trường hợp ít nơi đó là hữu ích:
$ echo hello > >(cat)
hello
Nguồn
2016-07-15 18:44:40
Ồ, điều đó thật tuyệt! Cảm ơn bạn đã trả lời, câu trả lời của tôi hoàn toàn đúng. –