Search code examples
rubynamed-pipes

Failing to read a named pipe being written to


I have a stream of data that I’m writing to a named pipe:

named_pipe = '/tmp/pipe' # Location of named pipe
File.mkfifo(named_pipe) # Create named pipe
File.open(named_pipe, 'w+') # Necessary to not get a broken pipe when ⌃C from another process later on

system('youtube-dl', '--newline', 'https://www.youtube.com/watch?v=aqz-KE-bpKQ', out: named_pipe) # Output download progress, one line at a time

Trouble is, while I can cat /tmp/pipe and get the information, I’m unable to read the file from another Ruby process. I’ve tried File.readlines, File.read with seeking, File.open then reading, and other stuff I no longer remember. Some of those hang, others error out.

How can I get the same result as with cat, in pure Ruby?

Note I don’t have to use system to send to the pipe (Open3 would be acceptable), but any solution requiring external dependencies is a no-go.


Solution

  • it looks like File.readlines/IO.readlines, File.read/IO.read need to load the whole temp file first so you don't see any be printed out.

    try File#each/IO.foreach which process a file line by line and it does not require the whole file be loaded into memory

    File.foreach("/tmp/pipe") { |line| p line }
    # or
    File.open('/tmp/pipe','r').each { |line| p line }