как работает труба - PullRequest
       8

как работает труба

0 голосов
/ 01 июня 2010

объясните мне, пожалуйста, как именно работает pipe, например, у меня есть этот фрагмент кода

set line = ($<)

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

Мне нужно выбрать все строки с 5 словами и после сортировки и после переноса, но я запутался, как это будет работать, в первую очередь "while" будет принимать всю информацию и после этого переносить ее для сортировки, или каждая итерация 'while' будет делать сортировку? заранее спасибо

Ответы [ 3 ]

3 голосов
/ 01 июня 2010

В случае, если OP заботится о внутренних элементах, канал часто реализуется как кольцевой буфер. То есть ОС откладывает кусок памяти и отслеживает, какой ее сегмент используется в данный момент (по мере необходимости оборачиваясь от конца к началу):

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

И мы контролируем поведение с помощью следующих правил:

  • Поведение с циклическим изменением выполняется путем выполнения all арифметики позиции по модулю длины буфера (обратите внимание, если наш язык использует 1 индексированный массив!).
  • Если front и back всегда одинаковы (как в начальном состоянии), то канал пуст и попытка чтения из него будет блокироваться, пока не будет что читать.
  • Если back равно (front-1) (по модулю длины, запомните!), Буфер заполнен, и попытки записи будут блокироваться, пока не будет места.
  • Чтение значения из канала возвращает содержимое в front и продвигается вперед на единицу.
  • Запись значения в начало конвейера back по одному и вставка нового ввода в это место.

Более сложные схемы, предусматривающие увеличение размера буфера при необходимости и памяти доступны (возможны и являются общими), и вышесказанное можно упростить, сделав сам буфер только одним символом long (это означает, что нам больше не нужны передние и задние панели), но вы платите за это большим количеством блокировок и ненужными переключениями контекста.

2 голосов
/ 01 июня 2010

Поскольку вы запускаете команду echo line | sort | ./calculate ${1} на каждой итерации, она будет выполняться каждый раз отдельно. Канал просто берет вывод команды слева и передает его на ввод команды справа.

1 голос
/ 01 июня 2010

Канал - это то, что считывает входные данные и выдает выходные данные одновременно, например, у вас может быть канал, который принимает входные данные, состоящие из строчных букв, канал будет изменяться (без изменения исходного источника). ввода, например файла данных) входных данных и измените их на заглавные буквы.

Трубы обрабатываются слева направо.

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

line по трубопроводу sort. Sort затем сортирует входные данные и выводит данные, которые, в свою очередь, передаются в процесс calculate, который ожидает некоторый ввод.

Может быть, проще представить это таким образом, подумайте об этом как о трубе или пластиковой трубе (разновидность водосточного желоба):

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

Edit:

Поскольку ваш первоначальный вопрос задан для интерпретации фрагмента кода, основанного на 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 <файл данных' или 'cat data_file | this_script'. </li>
  2. В то время как цикл чтения до достижения EOF (в вариантах Unix / Linux, его Ctrl + D, для Windows, его клавиша F6)
  3. Если количество строк достигло 5, то есть первые 5 строк, это та часть, которая беспокоит меня, и я не уверен на 100% ... но продолжу объяснять дальше ...
  4. 5 строк выводятся на экран, но из-за конвейера выходные данные становятся входными данными для сортировки, в свою очередь сортировка затем считывает данные с этих входных данных, сортирует данные и выводится, но опять же, из-за другой канал, рассчитать принимает входные данные из отсортированного вывода.
  5. Устанавливает переменную line для дополнительного ввода. и повторяет петли вокруг.

И чтобы ответить на ваш комментарий, при желании вы можете прикрепить трубы, я выделю строку 4, как показано:

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

Не стесняйтесь поиграть с комбинацией, кстати, я думаю, что line должно быть $line, если память мне не изменяет?

...