[erlang-questions] os:cmd/1 with return code
BJörn Lindqvist
bjourne@REDACTED
Fri Oct 17 13:24:11 CEST 2008
Hello good people,
I've been trying to implement and os:cmd/1 variant that also returns
the status code of the executed command. But it proved to be
exceedingly difficult.
First I tried something like os:cmd(Cmd ++ "; echo \n$?") and parsing
out the exit code. But that doesn't work if the command string is
broken in for example "ls ); echo \n$?" or "exit 99; echo \n$?".
Then I tried opening a port to "sh -c" like this:
port_open({spawn, "sh -c '" ++ Cmd ++ "'"}, [exit_status]),
and then reading from the port and receiving the exit_status
message. That works, but has escaping problems so it will fail if
e.g. Cmd is "ls 'foo bar'".
Then I tried opening a port to "sh", sending the command to it and
read the response from the port. Using this code:
mycmd(Cmd)->
Opts = [stream, exit_status, stderr_to_stdout, eof],
Port = open_port({spawn, "sh"}, Opts),
port_command(Port, Cmd ++ "\nexit\n"),
get_data(Port, []).
get_data(Port, Data) ->
receive
{Port, {data, Data1}} ->
get_data(Port, Data ++ Data1);
{Port, {exit_status, N}} ->
port_close(Port),
{N, Data}
end.
This mostly works, except when it doesn't. Sometimes I don't get the
{exit_status, N} message so the receive waits forever other times I
get other messages that I don't want. What should I do? It shouldn't
be that complicated to get this right. And why isn't this function
already in the OTP library?
--
mvh Björn
More information about the erlang-questions
mailing list