[erlang-questions] os:cmd/1 with return code

BJörn Lindqvist <>
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