以下人为的例子有效:
$ while read -r line; do echo $line; done < <(ls -al *.js)
...
但是,以下情况会给出一个错误:
$ while read -r line; do echo $line; done < <(ls -al {package.json,package-lock.json})
-bash: 0: ambiguous redirect
尽管过程替换内部的内容工作正常:
$ ls -al {package.json,package-lock.json}
-rw-r--r-- 1 me staff 764K Apr 19 10:23 package-lock.json
-rw-r--r-- 1 me staff 10K Apr 19 10:23 package.json
为什么?
这看起来像是 bash v3 中的一个错误(或至少是奇怪的),但在 v4 中得到了修复。正在发生的事情是,大括号扩展({package.json,package-lock.json}
)被应用于整个过程替换,而不仅仅是其中的参数。下面是一个简化的示例,我将用来演示正在发生的事情:
$ cat < <(echo {a,b})
-bash: 0: ambiguous redirect
让我们尝试一些变体:
$ cat <(echo {a,b}) # This works, sort of... each arg winds up on a separate line
a
b
$ echo <(echo {a,b}) # echo shows *two* different process substitutions are being done
/dev/fd/63 /dev/fd/62
$ grep -H . <(echo {a,b}) # This prints where it gets each line, showing it gets one letter/line from each substitution
/dev/fd/63:a
/dev/fd/62:b
。所以看起来<(echo {a,b})
正在将大括号扩展到<(echo a) <(echo b)
而不是<(echo a b)
。这适用于cat
和grep
,因为它们接受多个输入文件,但<
重定向只能接受一个输入文件(因此您会收到"不明确的重定向"错误)。
这似乎在 bash v4 中得到了修复(我已经在 v4.2.10 和 4.4.19 中测试过):
$ echo $BASH_VERSION
4.4.19(1)-release
$ cat < <(echo {a,b})
a b
$ cat <(echo {a,b})
a b
$ echo <(echo {a,b})
/dev/fd/63