Оболочка: взаимный трубопровод STDIN / STDOUT двух команд

Когда мы запускаем это с помощью оболочки POSIX,

$ cmd0 | cmd1 

STDOUT из cmd0 передается по трубопроводу в STDIN из cmd1.

Q: Вдобавок к этому, как я могу также передать STDOUT из cmd1 в STDIN из cmd0?

Обязательно ли использовать перенаправление из / в именованный канал (FIFO)? Мне очень не нравятся именованные каналы, потому что они занимают несколько путей к файловой системе, и мне нужно беспокоиться о столкновениях имен. Или мне нужно вызвать pipe (2) через C, Python или некоторые языки программирования общего назначения?

(Оба cmd0 и cmd1 выполняют некоторые сетевые операции ввода-вывода, поэтому они не будут блокировать друг друга навсегда.)

  • Скрипт пытается создать файлы, даже если им это не нужно?
  • Объединение пар файлов в цикле
  • Как выбрать строки из файла CSV на основе разных значений столбцов?
  • Как добавить оператор if (относительно пунктуации в слове) к этому сценарию bash
  • Linux + Solaris, как проверить последний процесс выполнения из списка процессов
  • Создание сценария Bash, который будет выполнять программу, и если он выйдет без сбоев, снова запустит его
  • Как сортировать коллекцию строк из разных файлов?
  • Выходной сигнал в ловушке, вызвавший вызванную ловушку?
  • One Solution collect form web for “Оболочка: взаимный трубопровод STDIN / STDOUT двух команд”

    В системах с двунаправленными трубами (не Linux) вы можете:

     cmd0 <&1 | cmd1 >&0 

    В Linux вы можете:

     { cmd0 < /dev/fd/3 | cmd1 3>&-; } 3>&1 | : 

    Это работает, потому что в Linux (и только для Linux) /dev/fd/x где x является fd для канала (с именем или нет), действует как именованный канал, то есть, открывая его в режиме чтения, вы получаете конец чтения и в режим записи дает вам конец записи.

    С помощью оболочки yash и ее x>>|y оператора перенаправления трубопровода :

     { cmd0 <&4 3<&- 4<&- | cmd1 >&3 3>&- 4>&-; } 3>>|4 

    С оболочками с поддержкой coproc :

    • ЗШ:

        coproc cmd0 cmd1 <&p >&p 
    • КШ

        cmd0 |& cmd1 <&p >&p 
    • bash4 +

        coproc cmd0 cmd1 <&"${COPROC[0]}" >&"${COPROC[1]}" 

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

      pipexec [A / path / to / cmd0] \
             [B / путь / в / cmd1] \
             '{A: 1> B: 0}' '{A: 0> B: 1}' 

    Или:

      dpipe cmd0 = cmd1 

    Или:

      socat EXEC: cmd0 EXEC: cmd1, nofork # с помощью сокетов
     socat EXEC: cmd0, текст = трубы EXEC: cmd1, nofork # с использованием труб 

    Я не знаю о python , но это также относительно легко делается в perl :

     perl -e 'pipe STDOUT,STDIN; exec "cmd0 | cmd1"' 

    В любом случае, остерегайтесь взаимоблокировок!

    Interesting Posts

    `command` vs` type` – найти файл программы в PATH пользователя

    Как заблокировать операцию управления трафиком (tc), если он запущен как не-root?

    Linux: Почему init и systemd используют так много операций ввода-вывода?

    Ноутбук падает на видеодрайвер Vesa

    Есть ли способ развернуть программное обеспечение виртуальной машины через командную строку на centos3

    Драйвер сенсорного экрана не инициализируется при первой загрузке, однако последующие загрузки

    Хранение гнома на флеш-диске?

    Временно используйте что-то еще в качестве домашней директории

    Есть ли инструмент командной строки для анализа частоты звука

    Разница между «cat» и «cat <

    Уведомление рабочего стола

    Как получить доступ к локальному зеркалу репозитория?

    Установить оболочку для входа, если отсутствует / etc / shells

    Сделать процесс unkillable в Linux

    найти шаблон поля в файле csv, а затем подсчитать уникальные значения полей

    Linux и Unix - лучшая ОС в мире.