下面代码摘自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. ES6语法(3)—— 用promise()对象优雅的解决异步操作

    Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大. 所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果. ...

  2. java框架之SpringBoot(3)-日志

    市面上的日志框架 日志抽象层 日志实现 JCL(Jakarta Commons Logging).SLF4J(Simple Logging Facade For Java).JBoss-Logging ...

  3. java框架之SpringBoot(5)-SpringMVC的自动配置

    本篇文章内容详细可参考官方文档第 29 节. SpringMVC介绍 SpringBoot 非常适合 Web 应用程序开发.可以使用嵌入式 Tomcat,Jetty,Undertow 或 Netty ...

  4. OrbSLAM2采集点云数据

    因为条件限制,在Windows10平台下实现OrbSLAM2+Kinect2点云数据采集. 1. 遇到问题,启动运行没多久就跟丢了,有的地方哪怕轻微的旋转甚至不动都无法跟踪. 原因:相机的标定参数不对 ...

  5. Keras序列模型学习

    转自:https://keras.io/zh/getting-started/sequential-model-guide/ 1.顺序模型是多个网络层的线性堆叠. 你可以通过将网络层实例的列表传递给  ...

  6. aws cloudwatch监控怎么通过钉钉机器人报警

    最近在完善海外业务在aws服务的CloudWatchh监控,发现CloudWatch报警通知要通过aws的sns服务,直接支持的通道有短信和邮件,但是我们想推到钉钉群里面的群机器人里面这个就要借助aw ...

  7. 大数据小视角3:CarbonData,来自华为的中国力量

    连续两篇文章都聊了不同的存储格式,这篇我们继续深入来看看在存储格式的演变之上有什么新的"黑科技".华为公司在2016年开源了类parquet的列存格式:CarbonData,并且贡 ...

  8. Netty返回数据丢包的问题之一

    这个问题是在一个群友做压力测试的时候发现的.使用客户端和netty创建一条连接,然后写了一个for循环不停的给服务器发送1500条信息,发现返回只有几百条.另外几百条不知道哪去了.查看代码,发现在服务 ...

  9. .Net 多线程 (1) Task

    多线程是一种有效提高程序工作效率的方法.当然为了效率需要使用更多的cpu,内存等资源. 并发是两个队列交替使用一台咖啡机,并行是两个队列同时使用两台咖啡机,如果串行,一个队列使用一台咖啡机,那么哪怕前 ...

  10. ASP.NET页面之间传值的方式之QueryString(个人整理)

    QueryString Querystring也叫查询字符串,这种页面间传递数据是利用网页地址URL.如果要从A页面跳转到B页面,则可以用Request.Redirect(”B.aspx?参数名=参数 ...