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

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

$ cmd0 | cmd1 

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

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

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

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

  • массив сценариев оболочки для элементов файлов
  • Использование параметров в скрипте
  • Вставить текст в определенные строки файла? со специальными символами
  • Как удалить файл с именем файла
  • наблюдение за выполнением скрипта с помощью скрипта monit, похоже, игнорирует каналы
  • Используя sshpass, код возврата (статус выхода) отличается по неизвестным причинам с использованием допустимых команд
  • Замена параметра скрипта скрипта
  • Изменение части строки в сценарии 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

    Удалите ^ C, когда CTRL + C

    Escape shell arg из одного сценария в другой

    Консоль Linux не может отображать какой-либо язык, кроме английского, в то время как терминал под Gnome может

    Защитная оболочка Power Broker или полный сценарий оболочки

    Что означает «хэширование» при использовании команды типа?

    Efibootmgr не добавляет идентификатор диска в формате HD

    Как получить сортировку unix для сортировки в том же порядке, что и Java (по значению unicode)

    Я не могу ввести символ вертикальной линии в терминале OSX

    mount -a – как игнорировать разделы, которые уже установлены или разделы, которые заняты

    Запустить GUI OS через гипервизор с сервера Linux?

    регулярное выражение egrep для раз в пять минут

    ISPConfig mail: запрещен доступ к ретрансляции

    Как определить самые последние доступные исправления для HP-UX 11.31 без контракта на поддержку?

    Откройте приложение на обычном рабочем столе в xmonad

    184 переменных среды слишком много?

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