我想知道重定向和管道之间的区别和关系。
- 管道是否仅用于将命令的 stdout 输出连接到另一个命令的 stdin 输入?
- 重定向是否仅用于将命令的 stdout 输出连接到文件,以及将文件连接到命令的 stdin 输入?但似乎有
command >& 2
。 - 管道
com1 | com2
可以通过重定向替换为com1 > tempfile; com2 < tempfile
。替换可以修改为不使用文件吗? - 重定向可以用管道代替吗?
感谢致敬!
答案1
是的。更准确地说,在 shell 中,管道将左侧命令的标准输出连接到右侧命令的标准输入。更准确地说,
foo | bar
对于 shell 来说意味着:- 创建一个管道。
- 分叉一个子进程,并将管道的写入端连接到其标准输出。然后
foo
在这个子进程中执行。 - 分叉一个子进程,并将管道的读取端连接到其标准输入。然后
bar
在这个子进程中执行。 - 等待两个子进程退出。
是的。普通重定向通过名称指示文件:
>foo
.另一种形式的重定向通过以下方式指示文件描述符。例如,>&2
意味着“将标准输出重定向到当前连接到的任何文件描述符 2”。关于该主题,请注意重定向是从左到右处理的。例如,要将标准输出和标准错误重定向到同一文件,请使用
foo >filename 2>&1
.在终端中键入的命令foo 2>&1 >filename
首先将标准错误连接到终端(此时标准输出和标准错误仍然连接到终端,因此不会有任何区别),然后将标准输出连接到文件。对,但是。 shell 中的管道构造创建了一个匿名管道;还有命名管道。
mkfifo f cat f # (in another terminal) echo hello >f
命名管道比管道少见得多。当需要连接两个独立启动的进程时使用它们;这种情况并不经常发生,但在必要时出现它是很好的。
请注意,您给出的替换:
foo >tempfile; bar <tempfile
是不同的:首先foo
将其所有输出写入临时文件,然后bar
开始运行。通过管道,命令可以并行运行。是的,但不是很有用。
cat input_file | some_command # a uselessly complicated way of writing some_command <input_file echo hello | tee output_file # a uselessly complicated way of writing echo hello >output_file
答案2
1) 是(除了 stderr)
prg 2>&1 | workwithboth
2) 是(除了 stderr)。
3)不,不完全是。
com1 > tempfile; com2 < tempfile.
完成com1后将启动com2,而
com1 | com2
可能会立即用 com2 处理 com1 输出的开头。是的 - 没有文件:使用管道。
4)你可以把窗当门,把门当窗,但为什么要这么做呢?建造门窗是有原因的——它们不是从天上掉下来的。