Mike
Mike

Reputation: 799

Running an external program with sequential inputs from Julia 0.5.1

I want to run an external program, lets call it program, sequentially piping inputs to its standard input. Lets call the inputs input_1, input_2 etc.

I then want the standard output of the program to be piped back into memory, for example a Julia data structure, or if this is not possible, written to a text file.

I can run the external program with:

run(`program input_1 input_2`)

which results in the standard output of the program being displayed to the shell.

I however need to feed the inputs sequentially, so cannot use this approach.

I have looked on the External Programs documentation page and I believe I should use the open function, but I cannot figure out how to use it.

When I run:

open(`program`)

the external program complains that it cannot run without an input.

This blog post is quite informative, and I believe something like:

(si,pr) = writesto(`program`)
write(si,input_1)
...
write(si, input_2)

might have worked on an older version of Julia, but the writeto function has been deprecated, as discussed here.

Additionally, I want the program to run in the background. Currently it spawns a new terminal window. I think this might be a function of the external program so I am not sure if this can be specified in Julia.

Upvotes: 2

Views: 595

Answers (1)

MBaz
MBaz

Reputation: 258

You may want to see what I ended up implementing in Gaston (a plotting program based on gnuplot). I needed to start gnuplot, and then send it commands via its stdin, while reading its output through stdout and any errors through stderr.

I implemented a popen3 function that executes a command and returns pipes to stdin, stdout, and stderr. The function is here: https://github.com/mbaz/Gaston.jl/blob/master/src/gaston_aux.jl#L431

Then, I access gnuplot's stdout and stderr pipes using async tasks (because reading from them is blocking). You can see that happening here: https://github.com/mbaz/Gaston.jl/blob/master/src/gaston_aux.jl#L5 all the way to line 52.

Edit (June 2019):

The best solution in Julia 1.x is to build a pipeline to connect the pipes, and then run to execute the pipeline. See here for the current implementation in Gaston.

Unfortunately, the documentation for Pipe is still non-existent, so I still consider this solution to be unofficial.

Upvotes: 3

Related Questions