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

我有一个Erlang启动脚本,可以像这样启动:

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

它从控制台运行时工作,但是当我从systemd运行它时没有任何错误信息失败。 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 

日志显示系统正确启动,然后突然终止,没有任何types的错误信息。 这到底是怎么回事?

原来你必须传递-noinput参数给erl。 否则,它将尝试打开stdin进行读取,失败,因为没有任何内容,终止没有任何形式的错误信息。

这工作:

 [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 

我刚刚设法使用systemd的erlang安装系统来安装代码库。 此过程符合有关设置嵌入式系统的erlang文档。 这是我学到的东西:

1)需要添加一个路径到达erts / examples中的安装工具。 这里是我的.erlang文件的摘录:

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

2)在erlang / doc / system_principles / create_target.html中进行构建

 target_system:create("mysystem"). 

3)将构建提取到临时位置。 对于我的应用程序,它从erlang完成:

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

4)编辑启动的最后一行,在其中运行erl并删除-daemon选项,并添加所需的任何erlang运行时参数,如-sname或-set_cookie。 这在erlang / doc / embedded / embedded_solaris.html#idm45326372314928中概述。 这里是我的系统中编辑的行:

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

5)安装到运行时的位置(不要忘记sys.config)
6)如下设置.services文件。 该文件存储在/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 

移除-daemon标志对于作为简单的服务是必不可少的,因为简单的服务运行,除非失败,否则不会返回。 在这个过程中使用run_erl允许erlang工具附加到守护进程以进行维护。