Erlang启动参数学习

本文介绍了Erlang的启动参数,包括设置节点名字、编译选项、运行时调用等。通过示例展示了如何使用-extra、-name、-sname、-eval、-s、-run、-make、-init_debug、-werl、-noshell、-noinput、-detached、-pa、-inet_dist_listen_min和-max、-remsh、-v和+P等参数,并提供了实用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目中脚本里大量使用erlang的启动参数配置,今天来学习一下关于erlang的启动参数

官方API

先贴出官方API的地址

前言

erlang启动参数主要有3种,分别是emulator flag, flags和plain arguments。下面我介绍几个常用的并且附上例子

启动时传参

这个用的场景比较多,比如你启动的时候想要传入一个常量配置的参数,他可能不大就几个字符不需要单独创一个文件来存,这时你就可以用它

-extra 要传的参数

[root@feng1 ~]# erl -extra test
Erlang/OTP 23 [erts-11.1] [source] [64-bit] [smp:1:1] [ds:1:1:10] [async-threads:1] [hipe]
Eshell V11.1  (abort with ^G)
1> init:get_plain_arguments().
["test"]

当然也可以多个,注意这个额外的传参最后用就行了

[root@feng1 ~]# erl -extra test1 test2 test3
Erlang/OTP 23 [erts-11.1] [source] [64-bit] [smp:1:1] [ds:1:1:10] [async-threads:1] [hipe]

Eshell V11.1  (abort with ^G)
1> init:get_plain_arguments().
["test1","test2","test3"]
2>

设置节点名字

这个相信大家学到tcp那章节的时候都用的不少了,长名称和短名称的节点名

-name ××@×× -setcookie ×××

-sname ×××

获取节点名

进入shell后获取节点名

[root@feng1 ~]# erl -sname feng
Erlang/OTP 23 [erts-11.1] [source] [64-bit] [smp:1:1] [ds:1:1:10] [async-threads:1] [hipe]

Eshell V11.1  (abort with ^G)
(feng@feng1)1> node().
feng@feng1
(feng@feng1)2> init:get_argument(sname).
{ok,[["feng"]]}
(feng@feng1)3> 

当然长名称也一样拿,注意变量名就是

[root@feng1 ~]# erl -name feng666@qq.com -setcookie 666
Erlang/OTP 23 [erts-11.1] [source] [64-bit] [smp:1:1] [ds:1:1:10] [async-threads:1] [hipe]

Eshell V11.1  (abort with ^G)
(feng666@qq.com)1> node().
'feng666@qq.com'
(feng666@qq.com)2> init:get_argument(name). 
{ok,[["feng666@qq.com"]]}
(feng666@qq.com)3> init:get_argument(sname).
error
(feng666@qq.com)4> 

为了方便后面的测试我们先创建一个简单的demo,里面有三个函数分别是0参1参2参

demo

test_start.erl

%%%-------------------------------------------------------------------
%%% @author fengshangjiong
%%% @copyright (C) 2021, <COMPANY>
%%% @doc
%%%
%%% @end
%%% Created : 12. 七月 2021 10:39
%%%-------------------------------------------------------------------
-module(test_start).
-author("fengshangjiong").

%% API
-export([test/0, test/1, test/2]).


test() ->
    io:format("test/0").

test(Args) ->
    io:format("test/1,A1 is ~w~n", [Args]).

test(Args1, Args2) ->
    io:format("test/2,A1 is ~w, A2 is ~w~n", [Args1, Args2]).

启动时编译(-compile)

我们将上面的demo单独放一个文件夹,里面除了他什么都没有

image-20210712104444130

我们用-compile启动参数来编译启动

GIF 2021-7-12 10-50-23

可以发现他帮我们把这个文件顺手编译了,且编译后的文件与源文件在同一目录下,如果需要同时编译多个模块在后面多加个对应模块名字即可,但是这个好像不是很好用?首先不能指定编译的文件在哪个目录下(一般是ebin),其次编译完也没有进入erlang shell,所以我们一般会用make:all()或者mmake模块来启动,(mmake支持多进程编译),在调用make:all之前需要用到启动时调用函数的方法-eval或者-s或者-run,这里先介绍这三个,在介绍make:all用法

启动时调用-eval

用法

-eval Expr

$ erl -eval 'test_start:test(1)'
Eshell V10.3  (abort with ^G)
test/1,A1 is 1
1>


$ erl -eval 'test_start:test(1,2)'
Eshell V10.3  (abort with ^G)
test/2,A1 is 1, A2 is 2
1>

其他例子

[root@feng1 ~]# erl -eval 'io:format("~w~n",[erlang:now()])'
Erlang/OTP 23 [erts-11.1] [source] [64-bit] [smp:1:1] [ds:1:1:10] [async-threads:1] [hipe]

{1626,59179,253130}
Eshell V11.1  (abort with ^G)
1>

启动时调用-s

用法

-s Mod Func Arg1 Args2 …

$ erl -s test_start test 1
test/1,A1 is ['1']
Eshell V10.3  (abort with ^G)
1>

$ erl -s test_start test 1 2
test/1,A1 is ['1','2']
Eshell V10.3  (abort with ^G)
1>

启动时调用-run

用法

-run Mod Func Arg1 Args2 …

$ erl -run test_start test 1
test/1,A1 is [[49]]
Eshell V10.3  (abort with ^G)
1>

$ erl -run test_start test 1 2
test/1,A1 is [[49],[50]]
Eshell V10.3  (abort with ^G)
1>

调用小结

可以发现-s和-run不管传多少个参数进去都被一个list解析,且-s和-run的参数传过去的格式也有细微的差别,想要传完整的参数还得-eval来

启动时编译(make:all)

把刚刚编译成功的test_start.beam删掉我们再试试,这次我们调用make:all/0方法试试给不给我们编译,注意这个方法在erl包中是自带的

image-20210712112014485

用-eval也好-s 也好 -run也行

pc@pc /cygdrive/e/work/sy2020Work/sy/erlang/demo/test_demo/src/etc/test
$ erl -s make all
Recompile: test_start
Eshell V10.3  (abort with ^G)
1>

pc@pc /cygdrive/e/work/sy2020Work/sy/erlang/demo/test_demo/src/etc/test
$ erl -run make all
Recompile: test_start
Eshell V10.3  (abort with ^G)
1>

pc@pc /cygdrive/e/work/sy2020Work/sy/erlang/demo/test_demo/src/etc/test
$ erl -eval 'make:all()'
Eshell V10.3  (abort with ^G)
1> Recompile: test_start
1>

GIF 2021-7-12 11-21-22

GIF 2021-7-12 11-21-43

GIF 2021-7-12 11-22-22

发现都可以编译到的,注意-eval后面的表达式格式就行了

启动时编译(-make)

还有一种就是直接带上-make启动就可以了,也会自动编译当前目录下的erl文件

mmake模块拓展

看到关于并行编译的用法一起放出来,mmake:all/1,发现比make多了一个参数,这个参数表示通过n个workers进程来编译你的代码

使用

erl -eval "case make:files([\"mmake.erl\"], [{outdir, \"ebin\"}]) of error -> halt(1); _ -> ok end" 
    -eval "case mmake:all(8,[$(MAKE_OPTS)]) of up_to_date -> halt(0); error -> halt(1) end."

(如果没编译成功则退出当前erlshell)

打印启动日志-init_debug

[root@feng1 ~]# erl -init_debug
{progress,preloaded}
{progress,kernel_load_completed}
{progress,modules_loaded}
{start,heart}
{start,logger}
{start,application_controller}
{progress,init_kernel_started}
{apply,{application,load,[{application,stdlib,[{description,"ERTS  CXC 138 10"},{vsn,"3.13.2"},{id,[]},{modules,[array,base64,beam_lib,binary,c,calendar,dets,dets_server,dets_sup,dets_utils,dets_v9,dict,digraph,digraph_utils,edlin,edlin_expand,epp,eval_bits,erl_abstract_code,erl_anno,erl_bits,erl_compile,erl_error,erl_eval,erl_expand_records,erl_internal,erl_lint,erl_parse,erl_posix_msg,erl_pp,erl_scan,erl_tar,error_logger_file_h,error_logger_tty_h,escript,ets,file_sorter,filelib,filename,gb_trees,gb_sets,gen,gen_event,gen_fsm,gen_server,gen_statem,io,io_lib,io_lib_format,io_lib_fread,io_lib_pretty,lists,log_mf_h,maps,math,ms_transform,orddict,ordsets,otp_internal,pool,proc_lib,proplists,qlc,qlc_pt,queue,rand,random,re,sets,shell,shell_default,shell_docs,slave,sofs,string,supervisor,supervisor_bridge,sys,timer,unicode,unicode_util,uri_string,win32reg,zip]},{registered,[timer_server,rsh_starter,take_over_monitor,pool_master,dets]},{applications,[kernel]},{included_applications,[]},{env,[]},{maxT,infinity},{maxP,infinity}]}]}}
{progress,applications_loaded}
{apply,{application,start_boot,[kernel,permanent]}}
Erlang/OTP 23 [erts-11.1] [source] [64-bit] [smp:1:1] [ds:1:1:10] [async-threads:1] [hipe]

{apply,{application,start_boot,[stdlib,permanent]}}
{apply,{c,erlangrc,[]}}
{progress,started}
Eshell V11.1  (abort with ^G)
1>

werl单独窗口启动eshell

这个里面打印的中文不会报错也不会乱码哦

GIF 2021-7-12 11-31-47

-noshell

跑完自己关了erl进程,适用于调用某模块完成指定逻辑(该参数关闭终端,但依然不会后台运行,有输出时会直接打印到当前屏幕)

pc@DESKTOP-QORRTM2 /cygdrive/e/work/sy2020Work/sy/erlang/demo/test_demo/src/etc/test
$ erl -noshell -eval 'io:format("~w~n",[erlang:now()])'
{1626,60913,474000}


如上面打印完erlang:now不会进入erlang shell

当然你要退出也可以在后面一个函数再调用一个erlang:halt()

$ erl -eval 'io:format("~w~n",[erlang:now()]),halt()'
Eshell V10.3  (abort with ^G)
{1626,61007,911000}

效果一致

-noinput

禁止终端输入

-detached

启动后 后台运行,效果等同于-noshell 和 -noinput 加在一起,一般用-detached

包含目录启动 -pa

比如刚才的test_start.erl我们在同级目录下编译了,如果我们返回上一级目录(没有test_start.beam的目录下)也想要能跑test_start怎么办呢

pc@DESKTOP-QORRTM2 /cygdrive/e/work/sy2020Work/sy/erlang/demo/test_demo/src/etc/test
$ ls
test_start.beam  test_start.erl

pc@DESKTOP-QORRTM2 /cygdrive/e/work/sy2020Work/sy/erlang/demo/test_demo/src/etc/test
$ cd ../

pc@DESKTOP-QORRTM2 /cygdrive/e/work/sy2020Work/sy/erlang/demo/test_demo/src/etc
$ ls
csdn.java  lll.erl      test               test_gen_server.erl
dfs.erl    my_bank.erl  test.erl           test_start.erl
exam1.erl  ooo.erl      test_demo.app.src  tt.hrl

pc@DESKTOP-QORRTM2 /cygdrive/e/work/sy2020Work/sy/erlang/demo/test_demo/src/etc
$ erl -s test_start test 1
{"init terminating in do_boot",{undef,[{test_start,test,[['1']],[]},{init,start_em,1,[{file,"init.erl"},{line,1115}]},{init,do_boot,3,[{file,"init.erl"},{line,823}]}]}}
init terminating in do_boot ({undef,[{test_start,test,[[_]],[]},{init,start_em,1,[{_},{_}]},{init,do_boot,3,[{_},{_}]}]})

Crash dump is being written to: erl_crash.dump...done


pc@DESKTOP-QORRTM2 /cygdrive/e/work/sy2020Work/sy/erlang/demo/test_demo/src/etc
$ erl -pa ./test -s test_start test 1
test/1,A1 is ['1']
Eshell V10.3  (abort with ^G)
1>

可以看到在没有的地方直接启动就dump了,但如果把含有beam文件的路径包括进来就好使了,多个路径也是可以的,项目中一般有好几个ebin文件夹也不奇怪

用法

-pa Dir1 Dir2

链接远程节点之前首先需要设置远程节点监听最小值和最大值,以免端口放行问题影响连接

节点端口设置

-inet_dist_listen_min 最小端口

-inet_dist_listen_max 最大端口

只需要在启动时带入即可

erl -inet_dist_listen_min 40000 -inet_dist_listen_max 44000

当然进入以后也是可以查询的

[root@feng1 ~]# erl -inet_dist_listen_min 40000 -inet_dist_listen_max 44000
Erlang/OTP 23 [erts-11.1] [source] [64-bit] [smp:1:1] [ds:1:1:10] [async-threads:1] [hipe]

Eshell V11.1  (abort with ^G)
1> init:get_argument(inet_dist_listen_min).
{ok,[["40000"]]}
2> init:get_argument(inet_dist_listen_max). 
{ok,[["44000"]]}
3>

远程节点 -remsh

先在本地开两个节点测试一下接管其他erlang控制台的例子

[root@feng1 ~]# erl -detached -name a@127.0.0.1
[root@feng1 ~]# erl -name b@127.0.0.1
Erlang/OTP 23 [erts-11.1] [source] [64-bit] [smp:1:1] [ds:1:1:10] [async-threads:1] [hipe]

Eshell V11.1  (abort with ^G)
(b@127.0.0.1)1> 
User switch command
 --> r 'a@127.0.0.1'
 --> j
   1  {shell,start,[init]}
   2* {'a@127.0.0.1',shell,start,[]}
 --> c
Eshell V11.1  (abort with ^G)
(a@127.0.0.1)1> node().
'a@127.0.0.1'
(a@127.0.0.1)2> 
User switch command
 --> j
   1  {shell,start,[init]}
   2* {'a@127.0.0.1',shell,start,[]}
 --> c

(a@127.0.0.1)2> 
User switch command
 --> j
   1  {shell,start,[init]}
   2* {'a@127.0.0.1',shell,start,[]}
 --> c 1

(b@127.0.0.1)1> node().
'b@127.0.0.1'
(b@127.0.0.1)2>

先用detached模式启动一个后台erlang控制进程,然后在开另一个erl控制台,通过^G(Ctrl+G)来进入用户切换模式,r链接,j列出当前可用用户列表,c切换。

如果退了一个节点,想把另一个节点detached的节点也关闭怎么办?可以用ps -ef|grep 名字搜一下进程直接kill掉

使用remsh链接

[root@feng1 ~]# erl -detached -name feng_test@127.0.0.1 -setcookie asd
[root@feng1 ~]# erl -setcookie asd -name feng_tt@127.0.0.1 -remsh feng_test@127.0.0.1
Erlang/OTP 23 [erts-11.1] [source] [64-bit] [smp:1:1] [ds:1:1:10] [async-threads:1] [hipe]

Eshell V11.1  (abort with ^G)
(feng_test@127.0.0.1)1> 
User switch command
 --> j
   1* {'feng_test@127.0.0.1',shell,start,[]}
 -->

可以看到进去以后就是remsh后面的节点了,当然也是可以通过^G模式下切换的

Eshell V11.1  (abort with ^G)
(feng_test@127.0.0.1)1> 
User switch command
 --> j
   1* {'feng_test@127.0.0.1',shell,start,[]}
 --> r 'feng_tt@127.0.0.1'
 --> j
   1  {'feng_test@127.0.0.1',shell,start,[]}
   2* {'feng_tt@127.0.0.1',shell,start,[]}
 --> c
Eshell V11.1  (abort with ^G)
(feng_tt@127.0.0.1)2> node().
'feng_tt@127.0.0.1'
(feng_tt@127.0.0.1)3> 

查看版本-v +v

两种都能看

[root@feng1 ~]# erl +V
Erlang (SMP,ASYNC_THREADS,HIPE) (BEAM) emulator version 11.1
[root@feng1 ~]# erl -v
Erlang/OTP 23 [erts-11.1] [source] [64-bit] [smp:1:1] [ds:1:1:10] [async-threads:1] [hipe]

Eshell V11.1  (abort with ^G)
1>

加内存 +P

这个知识进程表所用的内存

用法后面加size

erl +P 204800

暂时接触到这些,后面如果有新接触到常用的会持续更新

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

上上签i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值