Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Porcelain.exec does not capture stderr output #47

Open
markmark206 opened this issue Dec 5, 2017 · 2 comments
Open

Porcelain.exec does not capture stderr output #47

markmark206 opened this issue Dec 5, 2017 · 2 comments

Comments

@markmark206
Copy link

markmark206 commented Dec 5, 2017

stderr output produced by the process invoked via Porcelain.exec is not captured into result (printed by the program instead).

Repro info:

  1. External program, prints to stderr:
15:20:55 markmark ~$ cat mine_err.sh
#!/usr/bin/env bash
echo "mine stderr" 1>&2
15:23:39 markmark ~$ ./mine_err.sh
mine stderr

(if attempting a repro, please make sure to chmod +x mine_err.sh)

  1. Elixir code:
r = Porcelain.exec("/Users/markmark/mine_err.sh", [])
IO.inspect r
  1. Elixir output:
mine stderr
%Porcelain.Result{err: nil, out: "", status: 0}

^^^^ Note: mine stderr was printed by the program, but not included in Result.


For comparison, when the external program outputs to stdout, things work as expected:

  • external program, prints to stdout:
15:17:43 markmark  ~$ cat mine.sh
#!/usr/bin/env bash
echo "mine stdout"
15:20:23 markmark  ~$ ./mine.sh
mine stdout
  • elixir code:
r = Porcelain.exec("/Users/markmark/mine.sh", [])
IO.inspect r
  • elixir output (stdout text captured in out, as expected):
%Porcelain.Result{err: nil, out: "mine stdout\n", status: 0}
@amitizle
Copy link

amitizle commented Jan 21, 2018

Same for spawn_shell;

%Proc{pid: pid, out: {:send, out_pid}, err: {:send, err_pid}} = Porcelain.spawn_shell(command, out: {:send, self()}, err: {:send, self()})
IO.puts "out pid is #{inspect out_pid}, err pid is #{inspect err_pid}"
# out pid is #PID<0.177.0>, err pid is #PID<0.177.0>

I can write a full example with receive etc, but the problem is the same as @markmark206's.
In my case, I'm processing the output with GenServer.handle_info/2;

  def handle_info({pid, :data, :out, data}, state) do
    # do things with pid
    IO.puts data
    {:noreply, state}
  end

  @doc false
  def handle_info({_pid, :data, :err, data}, state) do
    IO.puts "ERROR: #{data}"
    {:noreply, state}
  end

The :out messages are being processed, while the err ones aren't.
The stderr ones are being just printed to screen, same as OPs description.

Also, thanks for all the work :)

EDIT: sorry for that! Reading the docs again, I see that :err is not supported for {:send, <pid>} using the basic driver.

@ivan
Copy link
Contributor

ivan commented Jan 21, 2018

markmark206, I think that is how it is intended to work, and Elixir's System.cmd does the same. See ":err – specify the way stderr will be passed back to Elixir." https://hexdocs.pm/porcelain/Porcelain.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants