我正在使用它systemd
在启动时启动一个程序并使其在后台运行。
我编写了一个简单的脚本来systemd
调用,该脚本将打印几行我希望在终端中看到的日志。
因此我设置了StandardOutput=journal+console
服务配置,但在终端和日志中都看不到输出。
frederick@Frederick-PC:~$ sudo systemctl start my_program.service
frederick@Frederick-PC:~$ journalctl _SYSTEMD_UNIT=my_program.service
No journal files were found.
-- No entries --
这些是我的服务配置和脚本。
/etc/systemd/system/my_program.service
[Unit]
Description=Start my_program client after system is booted
[Service]
Type=forking
ExecStart=/usr/bin/my_program.sh start
ExecStop=/usr/bin/my_program.sh stop
PIDFile=/run/my_program.pid
WorkingDirectory=/home/frederick/Applications/my_program-go/
StandardOutput=journal+console
[Install]
WantedBy=multi-user.target
/usr/bin/my_program.sh
#!/bin/sh
start() {
if [ -f /run/my_program.pid ]; then
kill -0 $(cat /run/my_program.pid) > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo "my_program has been already started"
exit 1
fi
fi
echo -n "Starting my_program... "
nohup /home/frederick/Applications/my_program-go/my_program-local -c /home/frederick/Applications/my_program-go/config.json >> /home/frederick/Applications/my_program-go/my_program.log 2>&1 &
if [ $? -gt 0 ]; then
echo "failed"
rm /run/my_program.pid > /dev/null 2>&1
else
echo $! | tee /run/my_program.pid
fi
}
stop() {
if [ -f /run/my_program.pid ]; then
echo -n "Stopping my_program... "
msg=$(kill $(cat /run/my_program.pid) 2>&1)
if [ $? -gt 0 ]; then
echo "failed"
echo $msg
else
rm /run/my_program.pid > /dev/null 2>&1
echo "succeeded"
fi
else
echo "my_program not started"
fi
}
restart() {
stop
start
}
case $1 in
start|stop|restart)
"$1"
;;
*)
echo "No such operation"
exit 1
;;
esac
我怎样才能看到echo
脚本中打印的那些行?请帮忙,谢谢。
答案1
我编写了一个简单的脚本供 systemd 调用……
…这就是问题的根源。你的“简单脚本”覆盖了标准输出和标准错误的发送位置。这完全没有必要。所有的重定向、PID 文件写入、nohup
-ing 和分叉对于某些东西来说都是完全不必要的已经已守护进程化,并且服务管理器已知道其 PID。您根本不需要该脚本的任何部分。相反,请像这样编写您的服务单元:
[单元] 描述=系统启动后启动my_program客户端 [服务] 类型=简单 用户=frederick ExecStart = / home / frederick / Applications / my_program-go / my_program-local -c /home/frederick/Applications/my_program-go/config.json 工作目录=/home/frederick/Applications/my_program-go/ 标准输出=日志+控制台 [安装] WantedBy=多用户.目标
调用任何必要的选项来阻止程序分叉,除非它确实实现了分叉就绪协议。很少有程序真正做到这一点。您的“简单脚本”肯定没有,因为它在守护进程初始化并准备就绪之前就退出了父进程。
进一步阅读
- 乔纳森·德·博因·波拉德(2015年)。systemd 的恐怖之屋. 常见问题答案。
- Systemd 启动后立即终止服务
- Yocto linux 服务脚本问题
- 手册
systemd.exec
页(以及 和systemd.service
)systemd.unit
。手册页中写道:服务、套接字、挂载点和交换设备的单元配置文件共享一组配置选项,这些选项定义了生成的进程的执行环境。此手册页列出了这四种单元类型共享的配置选项。