Можно ли создать цикл команд с помощью pipe или чего-то еще?

Можно ли создать цикл команд с помощью pipe или чего-то еще?

До сих пор я знал механизм конвейеризации как способ соединения серии команд путем соединения stdout одной команды со stdin следующей команды до тех пор, пока не будет достигнута последняя команда, которая соединит свой stdout с дисплеем или файлом.

Однако возможно ли создать цикл из команд, так чтобы стандартный вывод последней команды соединялся со стандартным вводом первой команды и, может быть, с помощью tee можно было бы как-то отобразить изменяющиеся значения определенного вывода?

решение1

Я не уверен насчет всех оболочек, которые есть, но в Bash это возможно, хотя и не с безымянными каналами. Так что не с символом |. Но если вы создадите именованный канал:

mkfifo fifo

Тогда вы можете использовать это:

<fifo cat | cat >fifo &

Теперь трубопровод работает в фоновом режиме, но ничего не делает. Но если вы подадите в трубопровод данные извне:

echo x >fifo

Трубопровод разблокируется и будет работать вечно. Или пока вы не осушит трубу:

cat fifo

Вывод появится один раз:

x

Если немного усложнить, то конвейер может быть таким:

<fifo cat | xargs -I@ echo @x >fifo &

Итак, он будет добавлять xк выходу на каждой итерации. Конечно, так и будет, но только после начала итераций, то есть как только канал разблокируется, то есть как только будет что-то читать. Как и раньше, это можно запустить вручную:

echo x >fifo

А теперь посмотрите, что topпоказывает. Должно быть довольно много активности и у , и catу xargs.

И так же, как и раньше, если вы осушаете трубопровод, вы увидите много xS в терминале, и трубопровод заблокируется.

Это был бы обоснованный вопрос, почему трубопровод опустошается. Почему команда, catзафиксированная в терминале, не оставляет ничего в цепи. Я этого не знаю.

решение2

Конечно, вы могли бы просто создать цикл и использовать переменные:

while true; do
    a=$(echo "$a" | grep "Hey" | cut -d" " -f2 | tee -a log)
done

Это сохранит последний вывод, который будет снова использован в начале.

решение3

Как уже было сказано, зацикленный конвейер невозможен в оболочке Unix без использования именованного канала (созданного с помощьюmkfifo(1)). Но вы можете сделать это на C; например, вот мойгрязно-простая реализация, который даже не дождался завершения процессов.

Я надеюсь вы найдете эту информацию полезной.

Связанный контент