If I open a Port in IEx for a script that prints anything to stderr, none of the output is printed with carriage returns. How can I fix this? I am running external software whose output I cannot control, so I can't just add the returns manually.
In /tmp/run.sh
#!/usr/bin/env bash
>&2 echo -e "line 1\nline 2\nline 3\nline 4"
In an IEx shell
iex(1)> Port.open({:spawn_executable, "/tmp/run.sh"}, [])
line 1
line 2
line 3
line 4
You can run the script under a wrapper that inserts a carriage return before the newline. Here's one such wrapper that uses bash
and perl
:
#!/usr/bin/env bash
"$@" 2>&1 | perl -pe 's/\n/\r\n/' 1>&2
Here's another using bash
and unix2dos
:
#!/usr/bin/env bash
"$@" 2>&1 | unix2dos 1>&2
Basically, anything that can read the original program's stderr
, replace newline with a carriage return and newline combination, and then write the result to stderr
will work.
Put one of these solutions in a file named /tmp/lf.sh
. Below we run it from iex with your original /tmp/run.sh
, first with just the original script and then with the wrapper:
iex(1)> Port.open({:spawn_executable, "/tmp/run.sh"}, [])
#Port<0.5>
iex(2)> line 1
line 2
line 3
line 4
nil
iex(3)> Port.open({:spawn_executable, "/tmp/lf.sh"}, [args: ["/tmp/run.sh"]])
#Port<0.6>
iex(4)> line 1
line 2
line 3
line 4
nil
iex(5)>