Using a bi-directional pipe to read and write from 'cmd'

Hi,

I’m using a bi-directional pipe for Julia 1.1.1 to communicate back and forth with an external process:

cvc4 = open(`cvc4 --incremental`, read=true, write=true)

The 2-way communication seems to work ok, except when I try to read a multi-line response from the process, and I don’t know a priori how many lines it consists of.

Let’s say the response is 3 lines. This works:

println(readline(cvc4.out))
println(readline(cvc4.out))
println(readline(cvc4.out))

But the obvious way of reading an unknown number of lines hangs:

println(readlines(cvc4.out))

I have tried various things, like readline() while !eof(cvc4.out), but nothing works.
Any help would be appreciated.

You could just call read(cvc4, String) and then split the lines yourself, via split(read(cvc4, String), '\n'), or perhaps you could also do:

while isreadable(cvc4)
  readline(cvc4)
end

Thanks. The first solution doesn’t work (hangs). The second one produces all the lines of the answer, and then hangs.
(Whether I run it from the REPL or from the command line).

I think you need at least one @async (see e.g., Collecting all output from shell commands), unless there is some kind of a marker from the external process that indicates the end of multi-line response. But, if you need to deal with multiple requests and responses, I don’t think there is a way to reliably relate a chunk of output lines to a response. So, using @async may not solve the actual problem.

You could use readuntil with an EOT character

I don’t know how @async works, and I don’t have control over the external process with which I’m communicating, so the EOT idea doesn’t work.

Anyhow, the solution turns out to be simple: Julia’s readavailable().
(Plus some processing of the result.)