帮酷LOGO
0 0 评论
  • 显示原文与译文双语对照的内容
文章标签:不同  RED  Redirect  DIFF  

问题:

这个问题可能有点愚蠢,但我不能真正看出重定向和管道之间的区别。

重定向用于重定向 stdout/stdin/stderr, 比如 ls> log.txt

管道用于将命令的输出作为另一个命令的输入,比如 ls | grep file.txt

但是为什么同样的事情有两个操作符?

为什么不编写 ls> grep 来传递输出,这不是一种重定向? 我所缺少的?


回答 1:

管道被用来将输出传递给另外一个的程序或者实用程序

重定向用于将输出传递给的文件或者流

示例: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

    编辑以提供注释中的更多详细信息:

    如果 > 尝试同时使用"传递给程序"和"写入文件",那么这两个方向可能会导致问题。

    你正在尝试向文件中写入的第一个示例:。 已经存在一个包含要覆盖的NAME的文件。 但是,文件是可以执行的。 它可能会尝试执行这个文件,传递输入。 你必须做一些类似于将输出写入新文件名的操作,然后重命名文件。

    如果在系统中指出了另一个命令,那么如果系统中的另一个命令具有相同的NAME ( 在执行路径中),那么该。 如果你想在当前文件夹中使用该 NAME 制作文件,你将被卡住。

    如果你键入命令,,它不会警告你命令不存在。 现在如果你喜欢 ls | gerp log.txt 它会告诉你 bash: gerp: command not found 如果 > 同时意味着,它将为你创建一个新文件,( 然后警告它不知道如何处理 log.txt )。


回答 2:

如果 foo> bar的意义取决于是否存在命令 bar,那么使用重定向更容易和更容易错误: 每次我想重定向到文件时,首先必须检查是否有名为destination目标文件like的命令。


回答 3:

两个运算符之间有一个重要的区别:

  • ls> log.txt --> 这里命令将输出发送到 log.txt 文件。

  • ls | grep file.txt --> 这里命令通过使用管道( | ) 发送ls命令的输出,by命令在前面的命令中搜索 file.txt。

  • 如果必须使用第一个方案执行相同的任务,则它将是:

    
    ls> log.txt; grep 'file.txt' log.txt
    
    
    
    

    因此管道( 使用 | ) 用于将输出发送到其他命令,而重定向( 使用 > ) 则用于将输出重定向到某些文件。


回答 4:

从Unix和Linux系统管理手册中:

重定向

shell 将符号的<。> 和>> 解释为指令,以将命令输入或者输出重新路由到一个英镑的文件输入或者输出中。

管道

要将一个命令的STDOUT连接到另一个的标准标准,可以使用| 符号,通常被称为管道。

所以我的解释是:如果是命令命令,使用管道。 如果要输出到文件或者从文件中输出,请使用重定向。


回答 5:

这两者之间有很大的句法差异:

  • 重定向是程序的参数
  • 管道分隔两个命令
  • 你可以考虑这样的重定向: cat [<infile] [>outfile]。这意味着顺序不重要: cat <infile> outfilecat> outfile <infile 相同。 你甚至可以将重定向与其他参数进行组合: cat> outfile <infile -bcat <infile -b> outfile 两者都是完美的,你可以将多个输入或者输出( 输入将按顺序读取,并且所有输出都将写入每个输出文件) 串联在一起: cat> outfile1> outfile2 <infile1 <infile2 重定向的目标或者源可以是文件名,也可以是流( 像 & 1,至少在bash中)的NAME。

    但是管道完全将一个命令与另一个命令分离,你不能将它们与参数混合在一起:

    
    [command1] | [command2]
    
    
    
    

    管道将所有写入command1标准输出并发送到command2的标准输入。

    你还可以合并管道和重定向。 例如:

    
    cat <infile> outfile | cat <infile2> outfile2
    
    
    
    

    第一个 cat 将从infile读取行,然后同时将每行写入outfile并将它的发送到第二个 cat

    在第二个 cat 中,标准输入首先从管道( infile的内容) 读取,然后从infile2读取,将每一行写入 outfile2. 运行这里命令后,outfile将是infile的副本,而outfile2将包含以下消息。

    最后,你实际上使用"这里字符串"重定向( 仅bash系列) 和反斜杠来实际执行类似于示例的操作:

    
    grep blah <<<`ls`
    
    
    
    

    将给出的结果与

    
    ls | grep blah
    
    
    
    

    但我认为重定向版本首先将所有的输出读入缓冲区( 在内存中),然后在每次向grep发送缓冲区时,将该缓冲区输入 grep,而管道版本将从1 开始,传递给 grep。


回答 6:

我今天在C 中遇到了一个问题。 本质上有管道不同的语义重定向,即使发送到 stdin。 我真的认为考虑到不同,管道应该去除了 stdin 之外的地方,所以我们可以用不同的方式来处理它,让它成为。

如果将一个程序输出管理为另一个 fstat,则看起来像 st_size,尽管 ls -lha/proc/{PID}/fd 显示了一个文件。 在重定向文件时( 至少在 debian wheezystretchjessie 香草和 ubuntu 14.0416.04 香草) 不是这样的。

如果你使用重定向的cat/proc/{PID}/fd/0,你可以重复读取多次,如你所喜欢的。 如果你用管道做这个,你会注意到第二次运行任务时,你不会得到相同的输出。


回答 7:

要添加到它的他答案,也有一些细微的语义差异- 比如 管道比重定向更容易关闭:


seq 5 | (head -n1; head -n1) # just 1


seq 5> tmp5; (head -n1; head -n1) <tmp5 # 1 and 2


seq 5 | (read LINE; echo $LINE; head -n1) # 1 and 2



第一个例子中,当第一次调用 head 结束时,它关闭管道,并终止 seq,因此没有可用的输入用于第二个 head

在第二个示例中,head使用第一行,但是当它关闭它自己的stdin 管道时,该文件将保持打开,以便下次调用使用。

第三个例子显示如果我们使用 read 来避免关闭管道,它仍然可以在子进程中使用。

因这里,"溪流"是我们通过( 标准标准等) 进行数据并流的事件,但是管道连接两个流程。

如果你对这些示例感到好奇和/或者惊讶,你可以进一步使用了解流程如何解析,E.g:


(trap 'echo seq EXITed> &2' EXIT; seq 5) | (trap 'echo all done' EXIT; (trap 'echo first head exited' EXIT; head -n1)


echo '.'


(trap 'echo second head exited' EXIT; head -n1))



有时第一个进程在 1 被打印之前关闭,有时。

我还发现使用 exec <&- 从重定向关闭流以近似管道( 尽管有错误) 行为有趣:


seq 5> tmp5


(trap 'echo all done' EXIT


(trap 'echo first head exited' EXIT; head -n1)


echo '.'


exec <&-


(trap 'echo second head exited' EXIT; head -n1)) <tmp5`






文章标签:RED  DIFF  不同  Redirect  

Copyright © 2011 HelpLib All rights reserved.    知识分享协议 京ICP备05059198号-3  |  如果智培  |  酷兔英语