Search code examples
processpipecrystal-lang

Piping data to a pager


I have a code sample in Ruby that pipes data to a pager in order to print it in portions to STDOUT:

input = File.read "some_long_file"
pager = "less"

IO.popen(pager, mode="w") do |io|
  io.write input
  io.close
end

I have no problem in adopting this to Crystal like this:

input = File.read "some_long_file"
pager = "less"

Process.run(pager, output: STDOUT) do |process|
  process.input.puts input
  process.input.close
end

But if I change pager = "more" than the Ruby example still works fine, but the Crystal snippet dumps all the data, instead of serving it in portions. How can I fix it?


Crystal 0.25.0 [7fb783f7a] (2018-06-11)
LLVM: 4.0.0
Default target: x86_64-unknown-linux-gnu


Solution

  • The more command tries to write it's user interface to stderr, so you need to forward that as well:

    Process.run(pager, output: STDOUT, error: STDERR) do |process|
      process.input.puts input
      process.input.close
    end
    

    Since you are reading a long file, you might consider not reading it into memory, but instead to pass the file descriptor to the pipe:

    input = File.open("log/development.log")
    pager = "more"
    Process.run(pager, input: input, output: STDOUT, error: STDERR)