如何从shell获取Erlang的发行版本号?


108

许多程序使用如下命令返回其版本号:

$ program --version
program (platform info) v1.2.3

这对于脚本编写程序的安装或维护以及系统管理员和朋友提供的一些其他受控自动化方法很有用。

问题

如何轻松获得Erlang(OTP)的版本号

网络上

这里是一些不令人满意的解决方案([1]和其他教程/ Erlang文档):

仿真器

$ erl
1> erlang:system_info(otp_release).
"R13B03"

很难编写脚本。我还没有找到erl从shell提示符执行单个命令的方法。

发布文件

$ cat /usr/lib/erlang/releases/RELEASES
[{release,"OTP  APN 181 01","R13B03","5.7.4",
      [{kernel,"2.13.4","/usr/lib/erlang/lib/kernel-2.13.4"},
       {stdlib,"1.16.4","/usr/lib/erlang/lib/stdlib-1.16.4"},
       {sasl,"2.1.8","/usr/lib/erlang/lib/sasl-2.1.8"}],
      permanent}].

解析天堂(带外壳)。

另一种选择也可以是检查安装路径,但是它不是可移植的(我的安装路径不包括版本)。

个人背景:我正在编写一个脚本,以在几台计算机上安装具有插件的相同版本的RabbitMQ。一些插件对OTP版本的要求最低,这就是这个问题的开始方式。

[1] http://forum.trapexit.org/viewtopic.php?p=42946


发行有什么不好?它是由Erlang解析的:-)
朱利安·丰德伦

糟糕,这没什么不好的!我根据上下文编辑了帖子。我的意思是用shell工具解析Erlang字符串。我的目标是为Erlang包编写SA任务脚本。
埃里克·普拉顿

我还不了解Erlang语法;我只想检查安装的版本是否支持Riak。担任主角并希望有一天,Erlang将提供一种更简单的方法来向依赖它的工具的管理员报告其版本。
伊恩·塞缪尔·麦克莱恩

erl --version。
Michael Dimmitt

Answers:


153
 erl -eval 'erlang:display(erlang:system_info(otp_release)), halt().'  -noshell

抱歉,我发布时没有看到更全面的先前答复
Odobenus Rosmarus 2012年

3
这将(no error logger present) error: "Error in process <0.0.0>在Windows 7上为我打印。-1
乔纳斯(Jonas)2014年

1
@andPat,您的建议将为我返回erlang shell的版本(例如7.0.2),而不是erlang本身(18在我的情况下)。
gdw2

6
从erlang:system_info的文档中:从OTP 17开始,OTP发行版号对应于主要的OTP版本号。没有erlang:system_info()参数提供确切的OTP版本。请参阅下面的答案,以获得更丑陋的命令,该命令还会在我的开发计算机上打印次要版本。
周杰伦2015年

2
在Windows 7上,我不得不用双引号替换单引号。erl -eval "erlang:display(erlang:system_info(otp_release)), halt()." -noshell
yohosuff

81

其他答案仅显示OTP 17的主要版本(来自docs的erlang:system_info)。这可以在我的开发机器上显示主要版本和次要版本:

erl -eval '{ok, Version} = file:read_file(filename:join([code:root_dir(), "releases", erlang:system_info(otp_release), "OTP_VERSION"])), io:fwrite(Version), halt().' -noshell

docs中所述,这将从适当的文件中读取。


2
谢谢,这很有用!此外,您还可以摆脱报价和\n也使代码,只改变一个短:erl -eval '{ok, Version} = file:read_file(filename:join([code:root_dir(), "releases", erlang:system_info(otp_release), "OTP_VERSION"])), io:fwrite(Version), halt().' -noshell
Dogbert '16

在Windows 7上,我必须将单引号与双引号交换(反之亦然)。erl -eval "{ok, Version} = file:read_file(filename:join([code:root_dir(), 'releases', erlang:system_info(otp_release), 'OTP_VERSION'])), io:fwrite(Version), halt()." -noshell
yohosuff

38

(因为我在过去三个月中至少搜索了3次,所以我在此处添加此答案)

从17.0版开始,发行版的版本号(17.0、17.1,...)采用新格式,但erlang:system_info(otp_release).仅返回主版本号。

为了获得完整的版本号,必须检查OTP_RELEASE已经提到的releases文件夹下文件的内容。

$ which erl
/usr/bin/erl
$ cd /usr/bin
$ ls -l erl
../lib/erlang/bin/erl
$ cd ../lib/erlang/
$ cat releases/17/OTP_RELEASE
17.3

编辑

# Some versions seem to have OTP_VERSION instead of OTP_RELEASE
$ cat releases/17/OTP_VERSION
17.4

根据您的描述,我找不到该文件,find / -name "OTP_RELEASE"也没有看到该文件,但是我安装了OTP17.x。我如何知道“ x”是什么?
NobbZ

1
@NobbZ我用其他信息更新了答案,我刚刚检查了一下,并且在我已经安装的当前Erlang / OTP版本(17.4)中,该文件实际上称为OTP_VERSION
juan.facorro 2015年

1
一条线cat $(dirname $(dirname `which erl`)/$(readlink `which erl`))/../releases/*/OTP_*
Lol4t0

14

初始化文档,由“ man erl”链接。

-eval Expr

在系统初始化期间扫描,解析和评估任意表达式Expr。如果这些步骤中的任何一个失败(语法错误,解析错误或评估期间的异常),Erlang都会停止并显示一条错误消息。这是播种随机数生成器的示例:

% erl -eval '{X,Y,Z} = now(), random:seed(X,Y,Z).'

本示例使用Erlang作为十六进制计算器:

% erl -noshell -eval 'R = 16#1F+16#A0, io:format("~.16B~n", [R])'  -s erlang halt
BF

如果指定了多个-eval表达式,则按指定的顺序对它们进行求值。-eval表达式使用-s和-run函数调用顺序评估(这也按指定的顺序进行)。与-s和-run一样,不会终止的评估会阻止系统初始化过程。

从而,

$ erl -noshell -eval 'io:fwrite("~s\n", [erlang:system_info(otp_release)]).' -s erlang halt

谢谢朱利安的详细信息。我怎么会忘记eval在手册中搜索关键词?
埃里克·普拉顿


7

查找 /usr/lib/erlang/releases/18/OTP_VERSION


可以,是的。与问题中的发行文件部分相同,您的建议书的问题在于它假设您知道安装路径。这样做的好处是可以获得完整版本。对我来说:18.2.1
埃里克·普拉顿

该文件在CentOS 7上不存在
Eduardo Cuomo

/usr/lib/erlang/releases -通过ansible安装
奥尔加,

4

erl + V或您可以使用erl -version

结果:Erlang(SMP,ASYNC_THREADS)(BEAM)仿真器版本5.8.5


5
这将返回erl仿真器版本,而不是Erlang发行版本号(例如“ R15B03”)。所有这一切都可能是如此简单;-)
埃里克·普拉

2

在PATH中找到erl并读取RELEASES文件以提取erlang版本号。

awk -F, 'NR==1 {gsub(/"/,"",$3);print $3}' "$(dirname $(readlink -f $(which erl)))/../releases/RELEASES"

1

打开终端并输入命令erl

您将获得以下输出:

Erlang R16B03(erts-5.10.4)[源代码] [64位] [smp:4:4] [异步线程:10] [内核轮询:false] Eshell V5.10.4(用^ G中止)

Erlang R16B03(erts-5.10.4)[源代码] [64位] [smp:4:4] [异步线程:10] [内核轮询:false] -这是语言版本

Eshell V5.10.4(中止带有^ G) -这是Shell版本


1

基于上述Jay的回答,我编写了以下可以使用的shell函数:

erlang () {
    if [[ $@ == "-v" ]]; then
        command erl -eval '{ok, Version} = file:read_file(filename:join([code:root_dir(), "releases", erlang:system_info(otp_release), "OTP_VERSION"])), io:fwrite(Version), halt().' -noshell
    else
        command erl
    fi
}

我常常忘记命令是erl不是erlang,所以这让我健忘的大脑只使用erlang就好像它是erl,并且erlang -v像我期望从类似elixir


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.