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:\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 执行命令的封装和参数详解的更多相关文章
- iptables命令、规则、参数详解
表 (table)包含4个表:4个表的优先级由高到低:raw-->mangle-->nat-->filterraw---RAW表只使用在PREROUTING链和OUTPUT链上 ...
- 【转】iptables命令、规则、参数详解
表 (table)包含4个表:4个表的优先级由高到低:raw-->mangle-->nat-->filterraw---RAW表只使用在PREROUTING链和OUTPUT链上 ...
- Linux挂载命令mount用法及参数详解
导读 mount是Linux下的一个命令,它可以将分区挂接到Linux的一个文件夹下,从而将分区和该目录联系起来,因此我们只要访问这个文件夹,就相当于访问该分区了. 挂接命令(mount) 首先,介绍 ...
- Webpack执行命令参数详解
一.概述前面的章节我们讲解了webpack的安装.webpack.config.js的 基本配置.webpack执行命名以及require方法的使用,不 知道大家有没有发现,当我们每次修改或者新增一个 ...
- Spring Boot启动命令参数详解及源码分析
使用过Spring Boot,我们都知道通过java -jar可以快速启动Spring Boot项目.同时,也可以通过在执行jar -jar时传递参数来进行配置.本文带大家系统的了解一下Spring ...
- JAVA命令参数详解
JAVA命令参数详解 JAVA命令详解 结构 说明 Java 和 OldJava JIT 选项 另请参阅 结构 java [ options ] class [ argument ... ] java ...
- 以太坊客户端Geth命令用法-参数详解
Geth在以太坊智能合约开发中最常用的工具(必备开发工具),一个多用途的命令行工具. 熟悉Geth可以让我们有更好的效率,大家可收藏起来作为Geth命令用法手册. 本文主要是对geth help的翻译 ...
- (转)Linux curl命令参数详解
Linux curl命令参数详解 命令:curl在Linux中curl是一个利用URL规则在命令行下工作的文件传输工具,可以说是一款很强大的http命令行工具.它支持文件的上传和下载,是综合传输工具, ...
- [转帖]Ipvsadm参数详解(常用命令)
Ipvsadm参数详解(常用命令) 2013年11月29日 12:41:40 怀素1980 阅读数:15901 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.cs ...
随机推荐
- spark-sql中的DataFrame文件格式转储示例
SparkConf sparkConf = new SparkConf() // .setMaster("local") .setAppName("DataFrameTe ...
- delphi操作sqlite3
Delphi SQLite 简明无废话上手指南SQLite下载http://www.sqlite.org/download.html SQLite FAQhttp://www.sqlitecn.org ...
- qemu对虚拟机的内存管理(二)
上篇文章主要分析了qemu中对虚拟机内存管理的关键数据结构及他们之间的联系,这篇文章则主要分析在地址空间发生变化时,如何将其更新至KVM中,保持用户空间与内核空间的同步. 这一系列操作与之前说的Add ...
- 万能的DBHelper帮助类
DBHelper类: 简单的理解就是一个工具箱,我要用锤子的时候就在里面拿,我要用剪刀的时候也可以在里面拿,前提是我们写的DBHelper够不够强大! 软件中的四大功能:增.删.改.查 我们要实现这 ...
- javaweb(3)之JSP&EL&JSTL
JSP(Java Server Page) 介绍 什么是 JSP ? 从用户角度看,JSP 就是一个网页. 从开发者角度看,它其实就是一个继承了 Servlet 的 java 类,所以可以直接说 JS ...
- python if 和 else
money = input("请输入你在学校有多少钱?")if int(money) > 5000: print("这个月可以潇洒潇洒了,每天可以出去吃大餐了.&q ...
- 2018-2019-1 20189203《Linux内核原理与分析》第五周作业
第一部分 课本学习 用户态.内核态和中断 1.内核态:处于高的执行级别下,代码可以执行特权指令,访问任意的物理地址,这时的CPU就对应内核态,对所有的指令包括特权指令都可以执行. 2.用户态:处于低的 ...
- 爬虫出现Forbidden by robots.txt(转载 https://blog.csdn.net/zzk1995/article/details/51628205)
先说结论,关闭scrapy自带的ROBOTSTXT_OBEY功能,在setting找到这个变量,设置为False即可解决. 使用scrapy爬取淘宝页面的时候,在提交http请求时出现debug信息F ...
- JaCoCo在Tomcat服务器上监控代码覆盖率的使用方法
简介 Jacoco是一个开源的覆盖率工具.Jacoco可以嵌入到Ant .Maven中,并提供了EclEmma Eclipse插件,也可以使用JavaAgent技术监控Java程序.很多第三方的工具提 ...
- Intellij IDEA junit 使用之org.junit不存在
在IDEA里面已经新建好了一个类,并加入了内容,然后创建测试类,快捷键(Ctrl+Alt+T)或者如图右键 Goto Test 创建后运行报错: Error:(3, 24) java: 程序包org. ...