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 ...
随机推荐
- RoR - Introduction to Active Record
Active Record: ORM ( Object-relational Mapping)Bridges the gap between relational databases , which ...
- 类的继承和C3算法
在Python的新式类中,方法解析顺序并非是广度优先的算法,而是采用C3算法,只是在某些情况下,C3算法的结果恰巧符合广度优先算法的结果. 可以通过代码来验证下: class NewStyleClas ...
- docker容器的操作
容器操作 1.查看本地容器 docker ps -a # 查看所有容器 docker ps # 查看所有正在运行的容器 2.容器的创建与启动 方法一:两步完成(强烈推荐方法)(1)创建 docker ...
- sx1278 手册参考
记录下芯片的重要数据和内容,方便查阅,无代码实现 参考程序地址:http://www.pudn.com/Download/item/id/3070942.html http://www.cirmal ...
- Python 操作 MySQL 的5种方式(转)
Python 操作 MySQL 的5种方式 不管你是做数据分析,还是网络爬虫,Web 开发.亦或是机器学习,你都离不开要和数据库打交道,而 MySQL 又是最流行的一种数据库,这篇文章介绍 Pytho ...
- Linux下的.txt文件复制到win下面不自动换行
原因:在Linux系统下, '\n'就是一个换行符,而在windows下,它是由回车换行组成,表示为 \r\n 解决方法:用Notepad++打开文档-->编辑-->文档格式转换--> ...
- Nginx 多域名配置
nginx绑定多个域名可又把多个域名规则写一个配置文件里,也可又分别建立多个域名配置文件,我一般为了管理方便,每个域名建一个文件,有些同类域名也可又写在一个总的配置文件里.一.每个域名一个文件的写法 ...
- C#-----类FileStream的使用
1.枚举类FileMode 指定操作系统打开文件的方式 CreateNew 指定操作系统应创建一个新的文件 Create 指定操作系统应创建一个新的文件. 如果该文件已存在,则会覆盖它 Open ...
- js语言精粹
1.typeof null == “object” ,所以不能通过typeof ~ == "object",判断为对象 : a.判断为null的,直接~ === null:b. ...
- P1605 迷宫
P1605 迷宫 这是一道毒瘤题... 这是一道广搜题 bfs ... 代码: #include<cstdio> #include<iostream> #include< ...