Use ports instead. When you open a port, you get a pid. Your process will then receive output from the command as messages from that pid. So you could do something like the following:
port = Port.open(...)
{:os_pid, ospid} = Port.info(port, :os_pid)
# note that if the program terminated before the call to Port.info, you'll get :undefined back
receive do
{^port, {:data, data}} -> ...
after <timeout> ->
System.cmd "kill #{ospid}"
end
If your program constantly produces output, you could fire a timer
{:ok, _} = :timer.send_after(1000, {:kill_this_process, ospid})
receive do
{^port, {:data, data}} -> ...
{:kill_this_process, ospid} ->
System.cmd "kill #{ospid}"
end
---
To create a port that is somewhat equivalent to System.cmd, use this:
sh = :os.find_executable('sh')
command = "something something"
port = Port.open({:spawn_executable, sh}, [:stream, :binary, {:args, ["-c", command]}, :use_stdio, :stderr_to_stdout, :exit_status])