¿Cómo puedo ejecutar un comando en tiempo de lectura para una tubería con nombre en Linux?

I'd like to have a program open that will write to a named pipe, but it doesn't write until someone actually reads from the named pipe. Is this achievable? How do I know when the pipe is read from?

preguntado el 04 de julio de 12 a las 09:07

Posible duplicación on unix.SO.com. Sounds like you want to put a buffer on your named pipe. This is sometimes called a "queue". -

3 Respuestas

Writting to a pipe will actually block until someone reads from the pipe

$ mkfifo f
$ printf "%s\n" "a" "b" "c" "d" > f & # on bg otherwise it blocks until someone reads it
$ cat < f
a
b
c
d
[1]+  Done                    printf "%s\n" "a" "b" "c" "d" > f

So you know when the pipe is read from when printf in the above example is Terminados.


so waiting to run a command once someone reads from the pipe can be achieved as

printf "%s\n" > f && run_some_command

but if the command is just sending data to the pipe (speculating here), you can send the data directly, as they will only be sent once somebody reads from the pipe

some_command > f # will block until f is read from

otra forma de encontrar if and who is reading or writing to a pipe is lsof. intentar

$ lsof f

and all processes reading or writting to f will be listed with their pids, process names, read or write actions.. see the man page.

Respondido 04 Jul 12, 10:07

I don't think there is a way, aside from implementing lock files or other semaphors/flags, to tell whether a named pipe has a listener. However, you might be able to detect things in the other direction. Linus Akesson wrote a blog post about using pipes to simulate logic gates. (It's a fascinating, über-geeky read.) In order to implement his ideas, he needed to write a tool that would check whether a pipe had data waiting, without actually taking the data out of the pipe.

You could take his code, compile it for your platform, then have a tool that only reads from a pipe once it has confirmed that data is waiting to be sent through it. Without knowing what you're really trying to achieve, I have no idea whether this solution is applicable to your actual problem.

The bottom line is that named pipes are not buffered, and provide no status indication without using possibly platform-specific hacks. Either the sending process will wait for a receiver, or a receiving process will hang around waiting for a sender.

It's likely that you want to use a more advanced message passing system than named pipes.

Respondido 05 Jul 12, 04:07

Well, the reason I want to use named pipes is that then the consumers don't even know that they are reading from something other than a file. This is a way for me to make dynamic files without having a build step - frew schmidt

Named pipes are visible in the filesystem and can be read and written just as other files are:

$ ls -la /tmp/testpipe
prw-r--r-- 1 mitch users 0 2009-03-25 12:06 /tmp/testpipe|

Named pipes are created via mkfifo or mknod:

$ mkfifo /tmp/testpipe
$ mknod /tmp/testpipe p

The following shell script reads from a pipe. It first creates the pipe if it doesn't exist, then it reads in a loop till it sees "quit":

#!/bin/bash

pipe=/tmp/testpipe

trap "rm -f $pipe" EXIT

if [[ ! -p $pipe ]]; then
    mkfifo $pipe
fi

while true
do
    if read line <$pipe; then
        if [[ "$line" == 'quit' ]]; then
            break
        fi
        echo $line
    fi
done

echo "Reader exiting"

Respondido 05 Jul 12, 03:07

Nice lesson there, but how does it answer the question? - Graham

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.