Search code examples
unixerlangpipeelixirmkfifo

How to write to stdin of external process in Elixir


Is it possible to write to stdin of external process In Elixir? Is NIF the only option right now?

The process that started from Elixir, blocks and wait for user input:

pid = spawn(fn ->
   System.cmd("sh", [
    Path.join([System.cwd, "sh", "wait_for_input"]),
   "Hello world"
  ])
end)

I would like to achieve something like that

IO.write pid, "Hello"
IO.write pid, "Hello again"

And this is the script

#!/bin/sh
while read data
do
  echo $data >> file_output.txt
done

Solution

  • You can use Port for this. Note that the read builtin of sh will only get data when a newline character is sent to sh, so you need to add that whenever you want the buffered data to be sent to read.

    $ cat wait_for_input
    while read data
    do
      echo $data >> file_output.txt
    done
    $ iex
    iex(1)> port = Port.open({:spawn, "sh wait_for_input"}, [])
    #Port<0.1260>
    iex(2)> Port.command port, "foo\n"
    true
    iex(3)> Port.command port, "bar\n"
    true
    iex(4)> Port.close(port)
    true
    $ cat file_output.txt
    foo
    bar