在哪裏可以做Erlang電話Retval = subprocess:call(["cmd", "arg1", "arg2", "arg3"])
?是否有一個Erlang os:cmd等價物,它取得一串字符串而不是單個命令?
如果我正在構建一個複雜的命令來執行,使用os:cmd/1很容易讓錯誤發生。與Python的subprocess.call()方法比較,在該方法中,我傳遞一個字符串列表並知道它是逐字傳遞給子進程的,沒有任何變化。
謝謝。
在哪裏可以做Erlang電話Retval = subprocess:call(["cmd", "arg1", "arg2", "arg3"])
?是否有一個Erlang os:cmd等價物,它取得一串字符串而不是單個命令?
如果我正在構建一個複雜的命令來執行,使用os:cmd/1很容易讓錯誤發生。與Python的subprocess.call()方法比較,在該方法中,我傳遞一個字符串列表並知道它是逐字傳遞給子進程的,沒有任何變化。
謝謝。
這就是我想到的。
-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.
難道你不能只做os:cmd(string:join(["cmd", "arg1", "arg2"], " "))
?
現在你可以做open_port({spawn_executable, Command}, [{args, [A1, ..., An]}])
,但是在os模塊中沒有方便的包裝。你可以拿os:cmd/1
的代碼,並調整它使用spawn_executable
。有關更多詳細信息,請查看erlang:open_port/2
的文檔。
這並沒有解決這個問題,即給予os:cmd/1的字符串將被shell處理。這將以系統依賴的方式擴展事物。例如,os:cmd(「echo'Hello'」)會將hello傳遞給沒有單引號的echo命令。很難弄到這樣的東西,這樣程序就會得到和Erlang一樣的參數字符串。你需要一種方法來運行程序,而不需要shell作爲中間人。 – RichardC 2010-02-10 12:49:56