2010-02-09 13 views

risposta

7

Questo è quello che ho trovato.

-module(mycmd). 
-export([cmd/2]). 

cmd(Cmd, Args) -> 
    Tag = make_ref(), 
    {Pid, Ref} = erlang:spawn_monitor(fun() -> 
      Rv = cmd_sync(Cmd, Args), 
      exit({Tag, Rv}) 
     end), 
    receive 
     {'DOWN', Ref, process, Pid, {Tag, Data}} -> Data; 
     {'DOWN', Ref, process, Pid, Reason} -> exit(Reason) 
    end. 

cmd_sync(Cmd, Args) -> 
    P = open_port({spawn_executable, os:find_executable(Cmd)}, [ 
      binary, use_stdio, stream, eof, {args, Args}]), 
    cmd_receive(P, []). 

cmd_receive(Port, Acc) -> 
    receive 
     {Port, {data, Data}} -> cmd_receive(Port, [Data|Acc]); 
     {Port, eof}   -> {ok, lists:reverse(Acc)} 
    end. 
0

Non puoi semplicemente fare os:cmd(string:join(["cmd", "arg1", "arg2"], " "))?

+2

Questo non risolve il problema, ovvero che la stringa data a os: cmd/1 verrà elaborata da una shell. Ciò espanderà le cose in modo dipendente dal sistema. Ad esempio, os: cmd ("echo 'Hello'") passerà Hello al comando echo senza le virgolette singole. È difficile ottenere questo tipo di cose in modo che il programma ottenga le stesse stringhe di argomento che hai sul lato di Erlang. Hai bisogno di un modo per eseguire il programma senza shell come middle-man. – RichardC

7

Al giorno d'oggi è possibile eseguire open_port({spawn_executable, Command}, [{args, [A1, ..., An]}]), ma non esiste ancora un wrapper conveniente per questo nel modulo os. È possibile prendere il codice per os:cmd/1 e modificarlo per utilizzare spawn_executable. Controlla i documenti per erlang:open_port/2 per maggiori dettagli.

Problemi correlati