简体   繁体   English

为什么我的Erlang启动脚本在控制台上运行,但从init系统(sysvinit,upstart,systemd)运行时不起作用?

[英]Why does my Erlang boot script work from console but does not work when run from init system (sysvinit, upstart, systemd)?

I have an Erlang boot script that I can launch like this: 我有一个Erlang启动脚本,我可以像这样启动:

/usr/bin/erl -boot /path/to/my-boot-script

It works when run from console, but fails without any error messages when I run it from systemd. 它从控制台运行时有效,但是当我从systemd运行它时失败而没有任何错误消息。 The systemd unit file looks like this: systemd单元文件如下所示:

[Unit]
Description=My daemon written in Erlang

[Service]
Type=simple
ExecStart=/usr/bin/erl -boot /path/to/my-boot-script
Restart=always

[Install]
WantedBy=multi-user.target

The log shows that the system boots properly and then terminates abruptly without any kind of error message. 日志显示系统正常引导,然后突然终止,没有任何类型的错误消息。 What the hell is going on? 这到底是怎么回事?

Turns out that you have to pass -noinput parameter to erl. 原来你必须将-noinput参数传递给erl。 Otherwise it will try to open stdin for reading, fail because there's nothing there and terminate without any kind of error message. 否则它将尝试打开stdin进行读取,失败因为没有任何内容并且没有任何类型的错误消息而终止。

This works: 这有效:

[Unit]
Description=My daemon written in Erlang

[Service]
Type=simple
ExecStart=/usr/bin/erl -noinput -boot /path/to/my-boot-script
Restart=always

[Install]
WantedBy=multi-user.target

I have just managed to use the erlang install system with systemd to install a code repository. 我刚刚设法使用带有systemd的erlang安装系统来安装代码库。 This procedure is compliant with the erlang documenation about setting up embedded systems. 此过程符合有关设置嵌入式系统的erlang文档。 Here is what I learnt: 这是我学到的:

1) Need to add a path to get to the install tools in erts/examples. 1)需要添加路径以获取erts / examples中的安装工具。 Here is an excerpt from my .erlang file for this: 以下是我的.erlang文件的摘录:

code:add_path(filename:join([os:getenv("ROOTDIR"),"lib/sasl-2.6/examples/ebin"])).

2) do the build as in erlang/doc/system_principles/create_target.html 2)在erlang / doc / system_principles / create_target.html中进行构建

target_system:create("mysystem").

3) extract the build into a temporary location. 3)将构建提取到临时位置。 For my application it done from erlang with: 对于我的应用程序,它是从erlang完成的:

target_system:install("code_repository", "/home/tony/Projects/code_repository/release_test").

4) edit the last line of start where it starts run erl and remove the -daemon option and add any erlang runtime parameters required like -sname or -set_cookie. 4)编辑它开始的最后一行开始运行erl并删除-daemon选项并添加所需的任何erlang运行时参数,如-sname或-set_cookie。 This is outlined in erlang/doc/embedded/embedded_solaris.html#idm45326372314928. 这在erlang / doc / embedded / embedded_solaris.html#idm45326372314928中列出。 Here is the edited line from my system: 这是我系统中编辑过的行:

$ROOTDIR/bin/run_erl  /tmp/ $ROOTDIR/log "exec $ROOTDIR/bin/start_erl $ROOTDIR $RELDIR $START_ERL_DATA -sname code_repository" 

5) Install to runtime location (don't forget about sys.config) 5)安装到运行时位置(不要忘记sys.config)
6) Set up .services file as follows. 6)如下设置.services文件。 This file is stored in /etc/systemd/system/code_repository.service: 该文件存储在/etc/systemd/system/code_repository.service中:

[Unit]
Description=Tonys Code Repository Daemon

[Service]
Type=simple
WorkingDirectory=/var/opt/code_repository
Environment=HOME=/var/opt/code_repository
ExecStart=/var/opt/code_repository/bin/start
Restart=yes

[Install]
WantedBy=multi-user.target

The removal of the -daemon flag is essential to operate as simple service, as simple services run and do not return unless they fail. 删除-daemon标志对于作为简单服务运行至关重要,因为简单服务运行并且除非它们失败否则不返回。 The use of run_erl as in this procedure allows erlang tools to attach to the daemon for maintenance.. 在此过程中使用run_erl允许erlang工具附加到守护程序以进行维护。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM