3

The problem I faced is exactly this one: http://www.linuxmisc.com/4-linux/d7863c256bccbfb6.htm

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.fifo

However, this has the disadvantage of the first command exiting after the second has finished. What I want is the same as:

txtplay

in 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?

  • echo does not send an EOF, it sends a new line. You can suppress the new line with the -n option. I guess the EOF you see is the EOF of the file you created. There is a good chance that I'm misunderstanding your issue, so this is only a comment. – bjanssen Jun 9 '14 at 13:01
  • 1
    The EOF is created when the echo is terminated, as pointed by @Luno. – justhalf Jun 9 '14 at 16:01
4

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.

  • Thank you for your answer. I have thought about this this morning, but that time I couldn't apply it to my use case. Apparently after some more thoughts, it's actually possible. Thanks :) – justhalf Jun 9 '14 at 16:02
2

If 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_exec

If 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.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.