下面代码摘自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:\n\tcwd: ~p\n\tcmd: ~s\n", [file:get_cwd(), Command0]),
?DEBUG("\topts: ~p\n", [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\nPort Opts: ~p\n", [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 ++ "\n", 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命令

执行如下

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

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

 13> tt7:sh("/bin/echo this is a $name", [{env,[{"name", "tanwen"}]}]).
this is a tanwen          %%这个是{use_stdout, true}的输出
{ok,"this is a tanwen\n"}

port 执行命令的封装和参数详解的更多相关文章

  1. iptables命令、规则、参数详解

    表    (table)包含4个表:4个表的优先级由高到低:raw-->mangle-->nat-->filterraw---RAW表只使用在PREROUTING链和OUTPUT链上 ...

  2. 【转】iptables命令、规则、参数详解

    表    (table)包含4个表:4个表的优先级由高到低:raw-->mangle-->nat-->filterraw---RAW表只使用在PREROUTING链和OUTPUT链上 ...

  3. Linux挂载命令mount用法及参数详解

    导读 mount是Linux下的一个命令,它可以将分区挂接到Linux的一个文件夹下,从而将分区和该目录联系起来,因此我们只要访问这个文件夹,就相当于访问该分区了. 挂接命令(mount) 首先,介绍 ...

  4. Webpack执行命令参数详解

    一.概述前面的章节我们讲解了webpack的安装.webpack.config.js的 基本配置.webpack执行命名以及require方法的使用,不 知道大家有没有发现,当我们每次修改或者新增一个 ...

  5. Spring Boot启动命令参数详解及源码分析

    使用过Spring Boot,我们都知道通过java -jar可以快速启动Spring Boot项目.同时,也可以通过在执行jar -jar时传递参数来进行配置.本文带大家系统的了解一下Spring ...

  6. JAVA命令参数详解

    JAVA命令参数详解 JAVA命令详解 结构 说明 Java 和 OldJava JIT 选项 另请参阅 结构 java [ options ] class [ argument ... ] java ...

  7. 以太坊客户端Geth命令用法-参数详解

    Geth在以太坊智能合约开发中最常用的工具(必备开发工具),一个多用途的命令行工具. 熟悉Geth可以让我们有更好的效率,大家可收藏起来作为Geth命令用法手册. 本文主要是对geth help的翻译 ...

  8. (转)Linux curl命令参数详解

    Linux curl命令参数详解 命令:curl在Linux中curl是一个利用URL规则在命令行下工作的文件传输工具,可以说是一款很强大的http命令行工具.它支持文件的上传和下载,是综合传输工具, ...

  9. [转帖]Ipvsadm参数详解(常用命令)

    Ipvsadm参数详解(常用命令) 2013年11月29日 12:41:40 怀素1980 阅读数:15901   版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.cs ...

随机推荐

  1. c++代码检测工具

    cppcheck是一款静态代码检查工具,可以检查如内存泄漏等代码错误,使用起来比较简单,即提供GUI界面操作,也可以与VS开发工具结合使用. 1.安装 一般会提供免安装版,安装完成后将cppcheck ...

  2. Django + Axios & Ajax post和get 传参

    话说千遍淡如水,不如代码来一通.   Axios post: let params = new URLSearchParams(); params.append('id',xx) axios({ ur ...

  3. 12.0-uC/OS-III任务调度

    调度器,决定了任务的运行顺序. uC/OS-III是一个可抢占的, 基于优先级的内核.根据其重要性每个任务都被分配了一个优先级.uC/OS-III支持多个任务拥有相同的优先级. 1.抢占式调度 uC/ ...

  4. 018-并发编程-java.util.concurrent.locks之-ReentrantReadWriteLock可重入读写锁

    一.概述 ReentrantLock是一个排他锁,同一时间只允许一个线程访问,而ReentrantReadWriteLock允许多个读线程同时访问,但不允许写线程和读线程.写线程和写线程同时访问.相对 ...

  5. javascript常用的操作

    1.concat()  连接两个或更多的数组,并返回一个新的数组.注意:该方法不会改变原数组 var arry1=["李四",“王二”]:  var arry2=['赵柳',“李旺 ...

  6. python3内置的tkinter参数释疑

    最近涉及到需要实现一个桌面UI的小游戏,所以就翻看了一些文档. 当然有介绍使用pyQT5的,但是本机安装的是python3.4,不想卸载掉这个版本,暂时还不能使用pyQT5. pyQT5需要pytho ...

  7. Python之__slots__ &运算符重载反向运算

    1.运算符重载之反向运算 class A: def __init__(self,x): self.x = x def __add__(self, other): try: x = other.x re ...

  8. Axis2的简单配置(完整版)

    Axis2的简单配置(终结版) 1.axis2 下载地址 axis2-1.6.2-bin.zip http://mirror.esocc.com/apache//axis/axis2/java/cor ...

  9. c#调用GetModuleFileNameEx获取进程路径

    原文最早发表于百度空间2009-09-04 [DllImport("Kernel32.dll", EntryPoint = "OpenProcess")]pub ...

  10. Python Redis 发布订阅

    发布者:服务器 订阅者:Dashboad和数据处理 频道主逻辑 import redis class RedisHelper: def __init__(self): # 链接服务端 self.__c ...