zoukankan      html  css  js  c++  java
  • port 执行命令的封装和参数详解

    下面代码摘自rebar_utils.erl

    -module(tt7).
    %-export([start/0]).
    -compile(export_all).
    
    -define(FAIL, abort()).
    -define(ABORT(Str, Args), abort(Str, Args)).
    
    -define(CONSOLE(Str, Args), io:format(Str, Args)).
    
    -define(DEBUG(Str, Args), io:format("debug :" ++ Str, Args)).
    -define(INFO(Str, Args), io:format("info :" ++ Str, Args)).
    -define(WARN(Str, Args), io:format("warn :" ++ Str, Args)).
    -define(ERROR(Str, Args), io:format("standard_error error :" ++ Str, Args)).
    
    -define(FMT(Str, Args), lists:flatten(io_lib:format(Str, Args))).
    
    sh(Command0, Options0) ->
        ?INFO("sh info:
    	cwd: ~p
    	cmd: ~s
    ", [file:get_cwd(), Command0]),
        ?DEBUG("	opts: ~p
    ", [Options0]),
    
        DefaultOptions = [{use_stdout, false}, abort_on_error], %% use_stdout表示是否输出cmd执行结果 abort_on_error表示错误时候退出
        Options = [expand_sh_flag(V)
                   || V <- proplists:compact(Options0 ++ DefaultOptions)],
    
        ErrorHandler = proplists:get_value(error_handler, Options),
        OutputHandler = proplists:get_value(output_handler, Options),
    
    %    Command = patch_on_windows(Command0, proplists:get_value(env, Options, [])),
        Command = Command0,
        PortSettings = proplists:get_all_values(port_settings, Options) ++
            [exit_status, {line, 16384}, use_stdio, stderr_to_stdout, hide],  %%open_port的一些常用参数
        ?DEBUG("Port Cmd: ~p
    Port Opts: ~p
    ", [Command, PortSettings]),
        Port = open_port({spawn, Command}, PortSettings),
    
        case sh_loop(Port, OutputHandler, []) of
            {ok, _Output} = Ok ->
                Ok;
            {error, {_Rc, _Output}=Err} ->
                ErrorHandler(Command, Err)
        end.
    
    sh_loop(Port, Fun, Acc) ->         %%接受port执行结果
        receive
            {Port, {data, {eol, Line}}} ->
                sh_loop(Port, Fun, Fun(Line ++ "
    ", Acc));
            {Port, {data, {noeol, Line}}} ->
                sh_loop(Port, Fun, Fun(Line, Acc));
            {Port, {exit_status, 0}} ->
                {ok, lists:flatten(lists:reverse(Acc))};
            {Port, {exit_status, Rc}} ->
                {error, {Rc, lists:flatten(lists:reverse(Acc))}}
        end.
    
    %%处理return_on_error、abort_on_error、use_stdout、cd、env这几个参数的结果
    expand_sh_flag(return_on_error)
    -> {error_handler, fun(_Command, Err) -> {error, Err} end}; expand_sh_flag({abort_on_error, Message}) -> {error_handler, log_msg_and_abort(Message)}; expand_sh_flag(abort_on_error) -> {error_handler, fun log_and_abort/2}; expand_sh_flag(use_stdout) -> {output_handler, fun(Line, Acc) -> ?CONSOLE("~s", [Line]), [Line | Acc] end}; expand_sh_flag({use_stdout, false}) -> {output_handler, fun(Line, Acc) -> [Line | Acc] end}; expand_sh_flag({cd, _CdArg} = Cd) -> {port_settings, Cd}; expand_sh_flag({env, _EnvArg} = Env) -> {port_settings, Env}. log_msg_and_abort(Message) -> fun(_Command, {_Rc, _Output}) -> ?ABORT(Message, []) end. log_and_abort(Command, {Rc, Output}) -> ?ABORT("sh(~s)~n" "failed with return code ~w and the following output:~n" "~s~n", [Command, Rc, Output]). abort() -> throw(execute_abort). abort(String, Args) -> ?ERROR(String, Args), abort().

    这样就能用port方法执行一些shell命令

    执行如下

     1 11> tt7:sh("/bin/echo this is a $name", [{env,[{"name", "tanwen"}]}]).
     2 info :sh info:
     3         cwd: {ok,"/home/erlang/fortest"}
     4         cmd: /bin/echo this is a $name
     5 debug : opts: [{env,[{"name","tanwen"}]}]
     6 debug :Port Cmd: "/bin/echo this is a $name"
     7 Port Opts: [{env,[{"name","tanwen"}]},
     8             exit_status,
     9             {line,16384},
    10             use_stdio,stderr_to_stdout,hide]    
    11 {ok,"this is a tanwen
    "}    %%没有输出默认的cmd结果,这个是port的打印

     去掉调试,修改DefaultOptions = [{use_stdout, true}, abort_on_error]

    1 13> tt7:sh("/bin/echo this is a $name", [{env,[{"name", "tanwen"}]}]).
    2 this is a tanwen          %%这个是{use_stdout, true}的输出
    3 {ok,"this is a tanwen
    "}
  • 相关阅读:
    如何:为 Silverlight 客户端生成双工服务
    Microsoft Sync Framework 2.1 软件开发包 (SDK)
    Windows 下的安装phpMoAdmin
    asp.net安全检测工具 Padding Oracle 检测
    HTTP Basic Authentication for RESTFul Service
    Windows系统性能分析
    Windows Server AppFabric Management Pack for Operations Manager 2007
    Mongo Database 性能优化
    服务器未能识别 HTTP 标头 SOAPAction 的值
    TCP WAIT状态及其对繁忙的服务器的影响
  • 原文地址:https://www.cnblogs.com/tudou008/p/5278489.html
Copyright © 2011-2022 走看看