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

Posted

技术标签:

【中文标题】如何从 shell 中获取 Erlang 的发布版本号?【英文标题】:How to get Erlang's release version number from a shell? 【发布时间】:2012-03-22 13:56:04 【问题描述】:

许多程序通过以下命令返回其版本号:

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

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

问题

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

在网上

这里有一些不满意的解决方案(来自trapexit forum 和其他教程/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 版本的要求最低,这就是这个问题的开始。

【问题讨论】:

RELEASES 有什么不好?它被 Erlang 简单地解析了 :-) 哎呀,这没什么不好!我根据上下文编辑了帖子。我的意思是用 shell 工具解析 Erlang 字符串。我的目标是为 Erlang 包编写 SA 任务脚本。 我还不懂 Erlang 语法;我只是想检查安装的版本是否支持Riak。以此为主角,并希望有一天 Erlang 能提供一种更简单的方法来向依赖它的工具的管理员报告其版本。 erl --version . 【参考方案1】:

init docs,由“man erl”链接。

-eval 表达式

在系统初始化期间扫描、解析和评估任意表达式 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

【讨论】:

感谢 Julian 提供的详细信息。我怎么会忘记搜索手册中的eval关键字?【参考方案2】:
 erl -eval 'erlang:display(erlang:system_info(otp_release)), halt().'  -noshell

【讨论】:

抱歉,我发帖时没有看到更全面的先前答案 这将为我在 Windows 7 上打印 (no error logger present) error: "Error in process <0.0.0>。 -1 @andPat,您的建议为我返回了 erlang shell 的版本(例如 7.0.2),而不是 erlang 本身(在我的情况下为 18)。 来自 erlang:system_info 的文档:从 OTP 17 开始,OTP 版本号对应于主要的 OTP 版本号。没有 erlang:system_info() 参数给出确切的 OTP 版本。 请参阅下面的答案,了解更丑陋的命令,该命令也会在我的开发机器上打印次要版本。 在 Windows 7 上,我不得不用双引号替换单引号。 erl -eval "erlang:display(erlang:system_info(otp_release)), halt()." -noshell【参考方案3】:

erl +V 或者你可以使用 erl -版本

结果:Erlang (SMP,ASYNC_THREADS) (BEAM) 模拟器版本 5.8.5

【讨论】:

这将返回 erl 模拟器版本,而不是 Erlang 发布版本号(例如“R15B03”)。这一切都可以如此简单;-)【参考方案4】:

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

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

【讨论】:

【参考方案5】:

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

从版本 17.0 开始,版本号(17.0、17.1、...)有新格式,但 erlang:system_info(otp_release). 仅返回主要版本号。

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

$ 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" 也没有看到它,但我安装了 OTP 17.x。我怎么知道“x”是什么? @NobbZ 我用附加信息更新了答案,我刚刚检查并在我安装的当前 Erlang/OTP 版本(17.4)中,该文件实际上称为OTP_VERSION 一行cat $(dirname $(dirname `which erl`)/$(readlink `which erl`))/../releases/*/OTP_*【参考方案6】:

其他答案仅显示 OTP 17 的主要版本(来自docs for 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

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

【讨论】:

谢谢,这很有用!此外,您可以去掉引号和\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 在 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【参考方案7】:

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

【讨论】:

行得通,是的。与问题中的 release file 部分相同,您的建议的问题是它假定知道安装路径。这里的好处是获得完整版。对我来说:18.2.1. 这个文件在 CentOS 7 上不存在 /usr/lib/erlang/releases - 通过 ansible 安装【参考方案8】:

打开终端输入命令erl

你会得到以下输出:

Erlang R16B03 (erts-5.10.4) [source] [64-bit] [smp:4:4] [async-threads:10] [kernel-poll:false] Eshell V5.10.4(使用 ^G 中止)

Erlang R16B03 (erts-5.10.4) [source] [64-bit] [smp:4:4] [async-threads:10] [kernel-poll:false] - 这是语言版本

Eshell V5.10.4(使用 ^G 中止) - 这是shell版本

【讨论】:

【参考方案9】:

要检索 EShell (Erlang Shell) 版本,您可以使用:

erlang:system_info(version).

并检索 Erlang OTP (Open Telecom Platform) 版本:

erlang:system_info(otp_release).

【讨论】:

最佳答案。尽管您希望 --version 可以工作。【参考方案10】:

您可以使用的简单命令:

erl --version

【讨论】:

这个命令通向shell。问题是如何获取版本,用于编写脚本。【参考方案11】:

根据上面 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,就好像它是erlerlang -v,就像我对@ 之类的期望一样987654327@.

【讨论】:

【参考方案12】:

我运行了系统和作品的更新

sudo apt-get update
sudo apt-get upgrade

【讨论】:

以上是关于如何从 shell 中获取 Erlang 的发布版本号?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Erlang shell 中运行 Erlang 应用程序

从 shell 脚本调用 erlang 文件的函数

如何从 Erlang 的衍生进程中获取返回值?

如何从 Erlang 中的对列表中获取元素

如何从 github 安装 erlang 模块?

从 Javascript(电子)执行 Erlang shell 命令不返回任何输出