0

请解释一下管道的工作原理,例如我有这段代码

set line = ($<)

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

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

4

3 回答 3

3

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

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

我们使用以下规则控制行为:

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

更复杂的方案涉及允许缓冲区在有需要并且内存可用时增长是可能的(并且确实很常见),并且可以通过使缓冲区本身只有一个字符长来简化上述方案(这意味着我们甚至不不再需要前后),但是您要付出很多锁定和许多不必要的上下文切换的代价。

于 2010-06-01T13:50:15.273 回答
2

由于您echo line | sort | ./calculate ${1}在每次迭代中都运行该命令,因此每次都将单独运行。管道仅获取左侧命令的输出并将其馈送到右侧命令的输入。

于 2010-06-01T13:06:16.203 回答
1

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

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

回声线 | 排序 | ./计算 ${1}

line被输送到sort. Sort然后对输入数据进行排序并输出数据,这些数据又通过管道传送到一个calculate需要一些输入的进程中。

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

输入 <---+---> 输出
          |
         管道

编辑:

由于您最初的问题要求解释基于 C Shell 的代码片段,所以不用多说...

1. 设置行 = ($<)
2.while(${#line} != 0)
3. if(${#line} == 5) 那么
4.回声线| 排序 | ./计算 ${1}
5.endif
6. 设置行 = ($<)
7.结束
  1. 从标准输入或文件中获取输入(这可以通过执行 'this_script < data file' 或 'cat data_file | this_script' 将文件重定向到此脚本来完成。
  2. While 循环读取直到到达 EOF(在 Unix/Linux 变体中,它的 Ctrl+D,对于 Windows,它的 F6 键)
  3. 如果行数已达到 5,即前 5 行,那就是困扰我的部分,我不是 100% 有信心......但会继续进一步解释......
  4. 5行被回显到输出,但是由于管道,输出成为排序的输入,然后排序然后从该输入读取,对数据进行排序并输出,但是又由于另一个管道,计算从排序的输出中获取输入。
  5. 设置变量line以包含更多输入。并重新循环。

为了回答您的评论,您可以根据需要添加管道,我将突出显示第 4 行,如图所示:

回声线 | 排序 | 独特 | ./计算 ${1}

随意玩弄这个组合,顺便说一句,如果我的记忆对我有帮助的话,我想line应该是$line这样吗?

于 2010-06-01T13:11:27.120 回答