为什么
echo "hello world" | cat
Run Code Online (Sandbox Code Playgroud)
工作时
cat < echo "hello world"
Run Code Online (Sandbox Code Playgroud)
才不是?我的(不正确的)直觉是管道会重定向stdout
到cat
as stdin
。
Has*_*tur 20
我们有两个相似但不同的东西
一条管道
echo "hello world" | cat # This is a pipeline
Run Code Online (Sandbox Code Playgroud)
管道控制运算符(|
和|&
)将命令的输出连接到管道中下一个命令的输入。因此第一个示例有效,echo
命令“Hello word”的输出与以下cat
命令的输入连接,如果未指定,则假定标准输入作为输入文件。事实上,我们可以从man cat
:
cat - 连接文件并在标准输出上打印
并在简单调用的示例下方 cat
cat Copy standard input to standard output
重定向,或者更好地尝试输入重定向 <
cat < echo "hello world" # This is an attempt of redirection
Run Code Online (Sandbox Code Playgroud)
在这种情况下,cat
命令从标准输入中获取输入,您使用运算符从...右侧的文件重定向,<
该文件<
不是文件。这是因为它不起作用。
从重定向部分 man bash
重定向输入
重定向输入会导致名称由单词扩展产生的文件被打开以读取文件描述符 n,如果未指定 n,则打开标准输入(文件描述符 0)。
在 bash 中它有不同的原因
cat <(echo "hello world")
过程替换
在支持命名管道 (FIFO) 或命名打开文件的 /dev/fd 方法的系统上支持进程替换。它采用
<(list)
或的形式>(list)
。进程列表运行时其输入或输出连接到 FIFO 或/dev/fd
. 该文件的名称作为扩展的结果作为参数传递给当前命令。如果使用>(list)
表单,写入文件将为列表提供输入。如果使用<(list)
表单,则应读取作为参数传递的文件以获得列表的输出。
cat <<< $(echo "hello world")
这里字符串
单词经历大括号扩展、波浪号扩展、参数和变量扩展、命令替换、算术扩展和引号删除。不执行路径名扩展和分词。结果作为单个字符串提供给其标准输入上的命令。
参考
man bash
并搜索redirection、pipeline、Here Strings和Process 替换man cat
只是因为我们使用它...