以下人为设计的示例起作用:
$ 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
那是为什么?
答案 0 :(得分:4)
这看起来像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