How to prevent terminating command to send EOF to named pipes?
The problem I faced is exactly this one:
I want to be able to run a program which takes stdin, and write data to it whenever I feel like it. I can do this with fifo named pipes. e.g.:
txtplay < named_pipe.fifo
echo "Hello World" > named_pipe.fifoHowever, this has the disadvantage of the first command exiting after the second has finished. What I want is the same as:
txtplayin effect, so I can just stick in my data whenever I like, and not worry about it seeing end-of-file. Unfortunately, I cannot simply do this, as I want the data to be sent to it to be processed through a filter before the program sees it.
Why don't I just load the program each time I want to send data to it? Too slow.
What I want, basically, is a way of redirecting the output of a given command to a fifo named pipe, without the end-of-file. While I'm at it, how does this EOF business work? Is there a special "EOF" command, or is it when no more data is received, or when the original program outputting the data exits?
Is there any solution to that?
22 Answers
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_pipeAnd 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.
1If you keep a handle open to the pipe, then it won't be closed by each echo command.
#!/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_execIf you remove that exec statement you will notice that the function hangs on the second echo, as Zenity stops when it sees EOF from the first echo.