Check if the named pipe / FIFO is open for recording

I created a named pipe for another process for recording and I want to check that another process is started correctly, but does not know its PID. Context launches the command on the screen , making sure that the command is run correctly. I was hoping this might work:

mkfifo /tmp/foo echo hello > /tmp/foo & lsof /tmp/foo 

Unfortunately, lsof does not report echo . inotifywait may be another option, but it is not always installed, and I really want to poll only once, and not block until some event.

Is there a way to check if a named pipe is open for writing? In general, is it open?


UPDATE:

Once both ends are connected, lsof works. This actually solves my problem, but for the sake of the question, I would be interested to know if it is possible to detect the initial redirect to the named pipe without reading.

 > mkfifo /tmp/foo > yes > /tmp/foo & > lsof /tmp/foo > cat /tmp/foo > /dev/null & > lsof /tmp/foo COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME yes 16915 user 1w FIFO 8,18 0t0 16660270 /tmp/foo cat 16950 user 3r FIFO 8,18 0t0 16660270 /tmp/foo 
+7
source share
2 answers

Update 2 . After playing with the inotify tools, there seems to be no way to get a notification that the named pipe has been opened for writing and is being blocked. This is probably why lsof does not show the handset until there is a reader and writer.

Refresh . After studying named pipes, I don’t think that there is any method that will work with named pipes on its own. Justification:

  • there is no way to limit the number of writers to a named pipe (without resorting to blocking)
  • all authors block if there is no reader
  • no authors block if there is a reader (presumably until the kernel buffers are full)

You could try not to write anything to the pipe with a short timeout. If the timeout expires, a write lock indicates that someone has already opened a channel for recording.

Note. As indicated in the comments, if the reader exists and is apparently fast enough, our test record will not be blocked, and the test essentially fails. Comment out the cat line below to check this out.

 #!/bin/bash is_named_pipe_already_opened_for_writing() { local named_pipe="$1" # Make sure it a named pipe if ! [ -p "$named_pipe" ]; then return 1 fi # Try to write zero bytes in the background echo -n > "$named_pipe" & pid=$! # Wait a short amount of time sleep 0.1 # Kill the background process. If kill succeeds, then # the write was blocked indicating that someone # else is already writing to the named pipe. kill $pid 2>/dev/null } PIPE=/tmp/foo # Ignore any bash messages from killing below trap : TERM mkfifo $PIPE # a writer yes > $PIPE & # a reader cat $PIPE >/dev/null & if is_named_pipe_already_opened_for_writing "$PIPE"; then echo "$PIPE is already being written to by another process" else echo "$PIPE is NOT being written to by another process" fi jobs -pr | kill 2>/dev/null rm -f $PIPE 
+4
source

you need two pipes, one for each direction: one is used to wait for readiness for a new data signal, the other only for data: in my case, the process is for files, line by line:

 mkfifo rw; cat file1 | while read l; do echo "$l" >w; read <r; done & cat file2 | while read ln; do if read l <w; then echo "$ln"; echo "$l"; fi; echo 1>r; done 
0
source

Source: https://habr.com/ru/post/1014741/


All Articles