I have an application that reads with $stdin and does some data processing. I want to turn on the signal handler to catch SIGINT / SIGTERM and finish work (which means completion of data processing and exit after completion). The tricky part is that I want it to stop reading from STDIN, but be able to process any buffered data. This means that you can start another application and transfer the same STDIN channel and resume processing when the previous application stopped.
The problem is that if I close STDIN, everything that was buffered is lost, or at least not available.
I am basically trying to do this:
#!/usr/bin/ruby Signal.trap('INT') do $stdin.close end f = File.open('/tmp/out', 'a') while (data = $stdin.read(4096)) != "" do f.write(data) end
It immediately IOError exception in the call to $stdin.read , although I know that it is reading some data (strace shows it).
(I donβt need to close the handset, I just do it to break the while . If there is a more elegant way to break the loop and get buffered data, I would gladly accept it.)
I know that this methodology works at the operating system level (the buffer buffer is preserved when transferred to another application), since I can run the following test and not lose any data:
# source.rb i = 0 loop do puts "%08d" % (i += 1) end
.
# reader.rb $stdout.write($stdin.read(9)) $stdin.close
.
ruby /tmp/source.rb | while true; do ruby reader.rb; sleep 1; done 00000001 00000002 00000003 00000004 00000005
source share