我知道<
,,<()
都<<
用于提供输入,而 >
,>()
用于重定向输出。
但我不知道它们之间有什么明显的区别,以及何时使用它们。请详细说明,并尽可能附上参考资料。谢谢
答案1
“何时使用”实际上取决于你正在做的事情。这就像问何时使用十字螺丝刀或一字螺丝刀。我可以告诉你它们都是什么,以及它们的作用,但何时使用它们则取决于你。
所有这些都在TLDP 高级 Bash 脚本指南。 如果你需要例子,就是这个地方。
< filename
从文件读取到 STDIN> filename
将 STDOUT 写入文件,覆盖任何内容。>> filename
将 STDOUT 写入文件,如果文件已存在则附加。<(command)
吸收内部命令的输出并提供文件名>(command)
为外部命令提供了文件名,但实际上将写入它的任何内容重定向到内部的 STDINcommand
。<<TOKEN
是 here document,又称 heredoc。它会将后面的内容读入 STDIN,直到TOKEN
再次看到为止。它对于多行内容很有用。它后面必须有一个换行符。除非您引用标记,否则 heredocs 支持变量替换。<<-TOKEN
与上文相同,只是它会忽略前导制表符(但只忽略制表符)。这对于保留源格式很方便,但实际上它只适用于制表符。它在 Stack Exchange 网站上毫无用处,因为他们用制表符代替空格 :(<<"TOKEN"
是不会替代的 heredoc$variables
。<<<"string"
是这里的字符串。它被读入 STDIN。这可以进行变量替换。| command
将当前 STDOUT 连接到command
|& command
将 STDOUT 和 STDERR 连接到 STDINcommand
(用于查找错误输出)1>
并2>
用于明确重定向 STDOUT 和 STDERR。>
暗示1>
所以你很少看到它明确使用。- 类似地
>&1
,>&2
可以用来重定向进入STDOUT 和 STDIN。 /dev/std{in,out,err}
还以符号链接的形式存在于基本输入/输出/错误文件描述符中。例如,当某些东西只接受文件名参数但你希望它写入 STDOUT 时,这非常方便。
答案2
Oli 的回答已经提供了很多解释。我在这个回答中的目的是提供几个实际的例子。
使用 [命令] < 文件进行输入重定向
重定向<
用于将文件的输出发送到命令。如果您能想象,虚拟线路从键盘拔出并插入文件。当您不想使用管道或不能使用管道时,它很有效。
例如,假设我有一个文件列表。我想对每个文件名运行某种测试(可能检查文件是否存在,或者是否是特定文件)。
while read FILENAME; do [ -d $FILENAME ] && echo $FILENAME;done < fileList.txt
通常这样的命令read
从 STDIN 接受输入,但使用<
运算符我们让它从文件接受输入。
此处有文档<<
当你想要对另一个命令或多个命令的输出进行操作,但又不想创建文件时,这非常有用。
在我的回答中bash 中 <<、<<< 和 < < 有什么区别?,我已经展示了两个简单的例子wc < <(echo bar;echo foo)
和diff <(ls /bin) <(ls /usr/bin)
。最后一个特别有用 - 我们比较两个命令的输出,而无需创建用于存储要比较的数据的文件。
使用 COMMAND1 > >(COMMAND2) 进行重定向
这个相当于管道。
xieerqi@eagle:~$ df > >(grep "dev" )
xieerqi@eagle:~$ /dev/sda1 115247656 83004376 26365932 76% /
udev 2914492 4 2914488 1% /dev
如图所示格雷格的维基,这可以用于向多个命令提供相同的输入
some_command | tee >(grep A > A.out) >(grep B > B.out) >(grep C > C.out) > /dev/null