问题描述
这个问题可能听起来有点愚蠢,但我不明白重定向和管道之间的区别。
重定向用于重定向stdout /stdin /stderr,例如ls > log.txt
。
管道用于将命令的输出作为输入提供给另一个命令,例如, ls | grep file.txt
。
但为什么有两个操作符为同一件事?
为什么不直接写ls > grep
来传递输出呢,这不就是一种重定向吗?我错过了什么?
最佳解决方法
管道用于将输出传递到另一个程序或实用程序。
重定向用于将输出传递给文件或流。
例如:thing1 > thing2
vs thing1 | thing2
thing1 > thing2
-
您的shell将运行名为
thing1
的程序 -
thing1
输出的所有内容都将放在名为thing2
的文件中。 (注 – 如果thing2
存在,它将被覆盖)
如果您想将程序thing1
的输出传递给名为thing2
的程序,您可以执行以下操作:
thing1 > temp_file && thing2 < temp_file
这将
-
运行名为
thing1
的程序 -
将输出保存到名为
temp_file
的文件中 -
运行程序名为
thing2
,假设键盘上的人输入temp_file
的内容作为输入。
然而,这很笨拙,所以他们将管道作为一种更简单的方式来做到这一点。 thing1 | thing2
与thing1 > temp_file && thing2 < temp_file
的功能相同
编辑提供更多的细节问题的评论:
如果>
试图同时“传递给程序”和“写入文件”,它可能会导致双向问题。
第一个示例:您正在尝试写入文件。已经有一个你想覆盖的文件名。但是,该文件是可执行文件。据推测,它会尝试执行该文件,传递输入。您必须执行一些操作,例如将输出写入新文件名,然后重命名文件。
第二个例子:正如Florian Diesch指出的那样,如果系统中其他地方有另一个命名相同的命令(在执行路径中)。如果您打算在当前文件夹中创建一个具有该名称的文件,则会卡住。
第三:如果你使用mis-type命令,它不会警告你该命令不存在。现在,如果你输入ls | gerp log.txt
,它会告诉你bash: gerp: command not found
。如果>
意味着两者,它会为您创建一个新文件(然后警告它不知道如何处理log.txt
)。
次佳解决方法
如果foo > bar
的含义取决于是否存在一个名为bar
的命令,它将使重定向变得更加困难和更容易出错:每当我想重定向到一个文件时,我首先必须检查是否有像我的目的地那样命名的命令文件。
第三种解决方法
两家操作符之间存在重大差异:
-
ls > log.txt
– >该命令将输出发送到log.txt文件。 -
ls | grep file.txt
– >该命令通过使用管道(|
)将ls的输出发送到grep命令,grep命令在前一个命令提供给它的输入中搜索file.txt。
如果您必须使用第一种方案执行相同的任务,那么它将是:
ls > log.txt; grep 'file.txt' log.txt
因此,使用管道(使用|
)将输出发送到其他命令,而使用重定向(使用>
)将输出重定向到某个文件。
第四种方法
从Unix和Linux系统管理手册:
Redirection
The shell interprets the symbols <,>, and >> as instructions to reroute a command’s input or output to or from a file.
Pipes
To connect the STDOUT of one command to the STDIN of another use the | symbol, commonly known as a pipe.
所以我的解释是:如果它是命令命令,请使用管道。如果您正在输出文件或从文件输出,请使用重定向。