我正在尝试安装RVM。有一个神奇的命令行:
bash < <(curl -s https://rvm.io/install/rvm)
我知道bash和curl是什么。我知道第一个<
是I / O重定向。但是<()
语法是什么意思?
此命令与
之间有什么区别bash < `curl -s https://rvm.io/install/rvm`
?(后一个命令不起作用)
答案 0 :(得分:20)
这是bash的process substitution。
表达式<(list)
被文件名替换,无论是命名FIFO还是/dev/fd
下的条目。因此,要实际重定向输入,您必须使用< <(list)
。
[编辑;忘了回答你的第二个问题]
反引号称为"command substitution"。与进程替换不同,它是POSIX shell规范的一部分(即,不是bash扩展)。 shell在反引号中运行命令并在命令行上替换其输出。所以这是有道理的:
cat < `echo /etc/termcap`
但这不会:
cat < `cat /etc/termcap`
后者与你的例子类似;它尝试使用命令的(复杂)输出作为重定向标准输入的文件名。
答案 1 :(得分:7)
其他人已经很好地回答了你的问题。我只是添加一个例子来构建它们...... 99%的时候,当我个人使用<()
时,它是在一次镜头中区分两个不同命令的输出。例如,
diff <( some_command ) <( some_other_command )
答案 2 :(得分:4)
io重定向的语法是
process < file
因此,您需要在io重定向之后出现的任何内容都是文件名。
反引号扩展字面上将命令的结果放入命令行。因此,
`curl -s https://rvm.io/install/rvm`
扩展到类似的东西 #!/ usr / bin / env bash ...
并且shell会被混淆,因为它会看到
bash < #...
而不是文件名。
<()
运算符是进程替换,它生成一个新进程以在(..)中运行命令。将创建一个用于捕获结果的新文件或管道。箭头指向左<()
而不是>()
这一事实意味着内部进程的输出将写入文件,该进程可以读取该文件。
在您的情况下,bash < <(...)
将被视为bash < /dev/fd/100
如果你真的想看看发生了什么,请运行
echo <(curl -s https://rvm.io/install/rvm)
答案 3 :(得分:3)
它被称为Process Substitution。