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

3879
justhalf

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

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

txtplay < named_pipe.fifo

echo "Hello World" > named_pipe.fifo

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

txtplay

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

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

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

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

3
echo не отправляет EOF, он отправляет новую строку. Вы можете подавить новую строку с помощью опции -n. Я думаю, что EOF, который вы видите, является EOF файла, который вы создали. Есть большая вероятность, что я неправильно понимаю вашу проблему, так что это всего лишь комментарий. bjanssen 10 лет назад 0
EOF создается, когда завершается `echo`, как указано @Luno. justhalf 10 лет назад 1

2 ответа на вопрос

4
Luno

Run all your commands in a sub-shell (or in bash, within parenthesis), and redirect the subshell to the named pipe.

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

And to answer the EOF question, EOF is written when the file handle closes. If you redirect from a program, you get EOF when that program (echo, in this case) terminates. By encapsulating multiple commands in parenthesis, you only get one EOF when the close parenthesis is reached.

Спасибо за ваш ответ. Я думал об этом сегодня утром, но в то время я не мог применить его к своему варианту использования. Видимо, после еще нескольких мыслей, это действительно возможно. Спасибо :) justhalf 10 лет назад 0
1
Pod

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

#!/usr/bin/env bash fifo_with_exec() { echo "fifo_with_exec"  readonly TMP_PIPE=$(mktemp -u) mkfifo -m 600 $ echo "pipe created: $"  # Here is the important bit exec 9<> $  zenity --progress --no-cancel < $ & zenity_pid=$! echo "zenity_pid: $"  echo "0" > $ echo "#Run command A" > $ echo "output of command A" sleep 2 echo "40" > $  echo "#Run command B" > $ echo "output of command B" sleep 2 echo "80" > $  echo "#Run command C" > $ echo "output of command C" sleep 0.5 echo "100" > $ } fifo_with_exec 

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