Как предотвратить завершение команды для отправки EOF на именованные каналы?

Проблема, с которой я столкнулся, именно эта: http://www.linuxmisc.com/4-linux/d7863c256bccbfb6.htm

Я хочу иметь возможность запускать программу, которая принимает стандартный ввод данных и записывать в нее данные всякий раз, когда мне это нравится. Я могу сделать это с именованными каналами fifo. например:

txtplay < named_pipe.fifo

echo "Hello World" > named_pipe.fifo

Однако это имеет тот недостаток, что первая команда завершается после завершения второй. То, что я хочу, так же, как:

txtplay

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

Почему бы мне просто не загружать программу каждый раз, когда я хочу отправить в нее данные? Слишком медленно.

По сути, мне нужен способ перенаправления вывода данной команды в именованный канал fifo без конца файла. Пока я в этом, как работает этот бизнес EOF? Существует ли специальная команда "EOF", или это когда больше данных не принимается, или когда выходит исходная программа, выводящая данные?

Есть ли какое-то решение для этого?

2 ответа

Решение

Запустите все ваши команды в вложенной оболочке (или в bash, в скобках) и перенаправьте подоболочку в именованный канал.

( 
     # some stuff
     echo "foo"
     # some other stuff
     echo "bar"
     # end of my commands
) > /home/foo/bar/named_pipe

И чтобы ответить на вопрос EOF, EOF записывается, когда дескриптор файла закрывается. Если вы перенаправляете из программы, вы получаете EOF, когда эта программа (в данном случае echo) завершается. Инкапсулируя в круглых скобках несколько команд, вы получаете только один EOF, когда закрывающая скобка достигнута.

Если вы держите дескриптор открытым для канала, то он не будет закрываться каждой командой echo.

#!/usr/bin/env bash
fifo_with_exec() {
    echo "fifo_with_exec"

    readonly TMP_PIPE=$(mktemp -u)
    mkfifo -m 600 ${TMP_PIPE}
    echo "pipe created:  ${TMP_PIPE}"

    # Here is the important bit
    exec 9<> ${TMP_PIPE}

    zenity --progress --no-cancel < ${TMP_PIPE} &
    zenity_pid=$!
    echo "zenity_pid: ${zenity_pid}"

    echo "0" > ${TMP_PIPE}
    echo "#Run command A" > ${TMP_PIPE}
    echo "output of command A"
    sleep 2
    echo "40"  > ${TMP_PIPE}

    echo "#Run command B" > ${TMP_PIPE}
    echo "output of command B"
    sleep 2
    echo "80" > ${TMP_PIPE}

    echo "#Run command C" > ${TMP_PIPE}
    echo "output of command C"
    sleep 0.5
    echo "100" > ${TMP_PIPE}
}
fifo_with_exec

Если вы удалите это выражение exec, вы заметите, что функция зависает во втором эхо, поскольку Zenity останавливается, когда видит EOF из первого эха.

Другие вопросы по тегам