1 | Job for xxx.service failed because a timeout was exceeded. See "systemctl status leanote.service" and "journalctl -xe" for details. |
在CentOS上编写自定义启停服务脚本时,有时脚本文件中特意设置很长的等待时间或要完成任务的时间本身就很长,例如下面的脚本:
1 2 3 4 5 6 | while true do echo 'trying netcat' # do something sleep 300s done |
如果在后台服务脚本中直接执行该脚本,就会收到超时信息,服务自动终止,这是我所不希望看到的:
1 2 3 4 5 6 7 8 9 10 11 12 | [Unit] Description=leanote.service After=network.target mongod.service [Service] Type=forking ExecStart=/data/leanote/bin/run.sh ExecStop=/bin/kill -SIGINT $MAINPID ExecReload=/bin/kill -USR2 $MAINPID [Install] WantedBy=multi-user.target |
执行“systemctl status 服务名”查看服务状态,可以看到由于systemd一直在等待run.sh脚本执行完成,但超时时间到了,自动结束了服务:leanote.service start operation timed out. Terminating.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | # systemctl status leanote.service ● leanote.service Loaded: loaded (/usr/lib/systemd/system/leanote.service; enabled; vendor preset: disabled) Active: failed (Result: timeout) since 五 2020-12-04 21:32:28 CST; 2min 24s ago Process: 4279 ExecStart=/data/leanote/bin/run.sh & (code=killed, signal=TERM) 12月 04 21:30:58 db-srv run.sh[4279]: DEBUG 21:30:58 revel controller_type.go:64: Registered controller: App\memberindex section=controller 12月 04 21:30:58 db-srv run.sh[4279]: DEBUG 21:30:58 revel controller.go:523: RegisterController:Registered controller section=controller controller=App\\memberindex 12月 04 21:30:58 db-srv run.sh[4279]: DEBUG 21:30:58 revel controller_type.go:64: Registered controller: App\memberuser section=controller 12月 04 21:30:58 db-srv run.sh[4279]: DEBUG 21:30:58 revel controller.go:523: RegisterController:Registered controller section=controller controller=App\\memberuser 12月 04 21:30:58 db-srv run.sh[4279]: DEBUG 21:30:58 revel server.go:106: InitServerEngine: Found server engine and invoking section=server name=go 12月 04 21:30:58 db-srv run.sh[4279]: Listening on.. 0.0.0.0:9000 12月 04 21:32:28 db-srv systemd[1]: leanote.service start operation timed out. Terminating. 12月 04 21:32:28 db-srv systemd[1]: Failed to start leanote.service. 12月 04 21:32:28 db-srv systemd[1]: Unit leanote.service entered failed state. 12月 04 21:32:28 db-srv systemd[1]: leanote.service failed. |
解决这个问题也很简单,借助“bash -c”,bash -c的作用是将一个长字符串当做一条完整的命令来执行,如果在脚本路径后面加上后台运行符号(&),run.sh脚本就会在后台运行,不会一直处于挂起状态,systemd也就不会一直等待run.sh执行完成了。经过测试,完全符合预期,因此,最终的解决方案是:
1 | ExecStart=/bin/bash -c "/data/leanote/bin/run.sh &" |