当我重新启动我的 Raspberry Pi (Stretch) 时,一个守护进程无法启动,因为/run/user/1000
它不存在。这是我的单位文件:
[Unit]
Description=SBFspot Upload Daemon
[Service]
User=pi
Type=forking
TimeoutStopSec=60
ExecStart=/usr/local/bin/sbfspot.3/SBFspotUploadDaemon -p /run/user/1000/sbfspotupload.pid 2>&1> /dev/null
PIDFile=/run/user/1000/sbfspotupload.pid
Restart=no
RestartSec=15
SuccessExitStatus=SIGKILL
[Install]
WantedBy=default.target
重试几次后,当我配置为Restart=on-failure
一切顺利时,但这并不是我真正想要的。我希望守护程序等待/run/user/1000
安装。我试过了,After=run-user-1000.mount
但它仍然失败。
这是可能的还是我必须坚持Restart=on-failure
?
/run/user/1000
,在用户 #1000 登录或显式启动 xyr 每用户服务管理之前,它当然不存在,这是一条红鲱鱼。使用它的整个机制不应该在那里。这个程序的错误 #215比你想象的要深得多。这个服务单元文件非常错误,程序本身的运行也是如此。有很多货物崇拜编程,基于对系统服务单元的基础知识的不了解。
ExecStart
设置会导致服务程序使用一些额外的参数运行,2>&1>
并且/dev/null
.main()
也是不必要的垃圾。fork()
运行,服务准备机制也不应该指定为Type=forking
. 就像现实世界中的许多程序一样,这个程序一开始并没有说分叉准备协议。User=root
是不必要的,实际上应该重新设计该服务,使其不需要以超级用户权限运行,而是在专用的非特权服务帐户的支持下运行。std::clog
.fork()
都不应该使用。服务管理处理所有这些,从会话领导到工作目录和 umask 再到标准 I/O,并正确处理。在服务管理器下使用时,该程序不会,也不应该尝试为自己做任何事情。你从 Boost 那里得到的一切都是错误的。
After
设置上有所不同,并且可以合并为一个。SuccessExitStatus=SIGKILL
存在一个问题,这是错误的。正常终止应该是优雅的,通过SIGTERM
,并且SIGKILL
应该被认为是异常的。(当然,整个output
文件机制是一个糟糕实现的本土日志机制,不应该在服务管理下使用,正如已经解释的那样。)这是 systemd 的默认设置。main()
。exit()
为在服务管理器下运行而正确实施的守护程序,无论是来自 daemontools、runit、s6、nosh、systemd 还是其他任何东西,都要短得多:
服务单元也更短:
systemctl status
可以使用andjournalctl
(-u
如果需要,使用选项和服务名称)查看日志输出。进一步阅读
logrotate
或newsyslog
在本世纪。. 经常给出答案。