管道是如何工作的

时间:2010-06-01 13:01:10

标签: csh tcsh

请告诉我管道是如何工作的,例如我有这段代码

set line = ($<)

while(${#line} != 0)
 if(${#line} == 5) then 
  echo line | sort | ./calculate ${1}
 endif 
 set line = ($<)
end

我需要选择包含5个单词的所有行,并在排序后和转移后,但我很困惑,它将如何工作,首先'while'将获取所有信息,然后将其转移到排序,或者每次迭代'while'都会排序吗?提前谢谢

3 个答案:

答案 0 :(得分:3)

如果OP关心内部,管道通常被实现为循环缓冲区。这就是操作系统放弃了一大块内存并跟踪它当前正在使用的部分(根据需要从末尾到开头):

+-------+
| front |
+-------+
      |             +-------+
      |             | back  |-------\
      V             +-------+        V
+---+---+---+---+---+      +---+---+----+---+---+---+
|   | c | o | n | t |  ... | e | r | \n |   |   |   |  // the buffer itself
+---+---+---+---+---+      +---+---+----+---+---+---+

我们用这些规则来控制行为:

  • 环绕行为是通过 all 以位置算术模数缓冲区长度来完成的(注意我们的语言是否使用了1个索引数组!)。
  • 如果frontback始终相同(如在起始条件中),则管道为空并且尝试从中读取将阻塞,直到有东西要读。
  • 如果back(front-1)(模数长度,请记住!),缓冲区已满,尝试写入将阻塞,直到有空间。
  • 从管道中读取值会返回front处的内容,然后前进一个。
  • 将管道预先back的值写入一个,并在此位置插入新输入。

更复杂的方案涉及在需要内存时允许缓冲区增长是可能的(并且确实很常见),并且通过使缓冲区本身只有一个可以简化上述方案字符长(意味着我们甚至不需要正面和背面)但你需要花费大量的锁定和许多不必要的上下文切换。

答案 1 :(得分:2)

由于您在每次迭代中都运行echo line | sort | ./calculate ${1}命令,因此每次都会单独运行。管道只接受左侧命令的输出,并将其输入右侧命令的输入。

答案 2 :(得分:1)

管道是同时读取输入并产生输出的东西,例如,您可以使用管道接收由小写字母组成的输入,管道将修改(不更改原始源输入数据,例如数据文件)输入数据并将其改为大写字母。

管道以从左到右的方式处理。

echo line | sort | ./calculate ${1}

line通过管道传输到sortSort然后对输入数据进行排序并输出数据,然后将数据通过管道传输到期望输入的calculate进程。

以这种方式可视化更容易,将其视为管道或塑料管(雨水槽品种):

INPUT <---+---> OUTPUT
          |
         pipe

<强> 编辑:

由于您的原始问题要求解释基于C Shell的代码段,而不再赘述......

1. set line = ($<)
2. while(${#line} != 0)
3. if(${#line} == 5) then 
4.  echo line | sort | ./calculate ${1}
5. endif 
6. set line = ($<)
7. end
  1. 从标准输入或文件中获取输入(这可以通过执行'this_script&lt; data file'或'cat data_file | this_script'将文件重定向到此脚本来完成。
  2. while循环读取直到达到EOF(在Unix / Linux变体中,其Ctrl + D,对于Windows,其F6键)
  3. 如果行数已经达到5,即前5行,那就是困扰我的部分,并且不会100%自信......但会继续进一步解释..
  4. 输出回显5行,但由于管道,输出成为sort的输入,然后排序然后从该输入读取,对数据进行排序并输出,但是由于另一个管道,calculate从输出的输出中获取输入。
  5. 将变量line设置为包含更多输入。并重新循环。
  6. 如果您愿意,可以回答您的评论,我会突出显示第4行:

    echo line | sort | uniq | ./calculate ${1}
    

    顺便说一句,如果我的记忆能够正确使用,我认为line应该是$line,请随意使用该组合。