为什么我的 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)?
我有一个可以像这样启动的 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
日志显示系统正常启动,然后突然终止,没有任何错误消息。这到底是怎么回事?
原来你必须将 -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) 编辑 start 的最后一行 运行 erl 并删除 -daemon 选项并添加所需的任何 erlang 运行time 参数,如 -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 标志对于作为简单服务运行至关重要,作为简单服务 运行 并且不要 return 除非它们失败。在这个过程中使用 run_erl 允许 erlang 工具附加到守护进程以进行维护..
我有一个可以像这样启动的 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
日志显示系统正常启动,然后突然终止,没有任何错误消息。这到底是怎么回事?
原来你必须将 -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) 编辑 start 的最后一行 运行 erl 并删除 -daemon 选项并添加所需的任何 erlang 运行time 参数,如 -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 标志对于作为简单服务运行至关重要,作为简单服务 运行 并且不要 return 除非它们失败。在这个过程中使用 run_erl 允许 erlang 工具附加到守护进程以进行维护..