我编写了一个bashscript,内容如下:
#!/bin/bash
cd /opt/ut_server/System
./ucc-bin-linux-amd64 server DM-Rankin?game=XGame.xDeathMatch?mutator=AntiTCC2009r6.MutAntiTCCFinal,utcompv17a.MutUTComp?AdminName=admin?AdminPassword=1111 ini=server.ini -port=1234 -log=s9.log -nohomedir &
sleep 10
echo "finish ucc"
exit 0现在,我希望从一个单元文件和systemd开始:
[Unit]
Description=Unreal Tournament 2004 Server
After=network.target
[Service]
WorkingDirectory=/home/unreal-user/
User=unreal-user
Group=unreal-user
Type=forking
ExecStart=/home/unreal-user/start_ut_serv.sh &
ExecStartPost=/bin/bash -c "umask 022; echo $MAINPID > /home/unreal-user/ut2k4-server.pid"
ExecReload=/bin/kill -HUP $MAINPID
ExecStop=/bin/kill -9 $MAINPID
TimeoutSec=400
ExecRestart=/bin/kill -9 $MAINPID && /home/unreal-user/start_ut_serv.sh
PIDFile=/home/unreal-user/ut2k4-server.pid
RestartSec=30
Restart=on-failure
#Restart=always
[Install]
WantedBy=multi-user.target当我启动服务文件时,我得到了一个错误,例如:
ut2k4-serv.service: Start operation timed out. Terminating.
systemd[1]: ut2k4-serv.service: Control process exited, code=killed, status=15/TERM为什么这是时间安排?如何处理这个问题?
当我开始使用bashscript手册时,它似乎仍然存在于STDOUT中,即使在其中指定了一个作业?这只是好奇..。
发布于 2020-06-19 22:35:42
这主要是从systemd.service文档复制粘贴,因为它基本上是足够的。
Type=<...> --exec类型类似于simple,但服务管理器将考虑在执行主服务二进制文件后立即启动该单元。服务经理将把后续单位的启动推迟到那个时候。(换句话说:simple在fork()返回后立即继续执行进一步的作业,而exec不会在服务流程中的fork()和execve()成功之前继续工作。)请注意,这意味着当服务的二进制文件无法成功调用时,用于systemctl服务的exec启动命令行将报告失败(例如,因为所选的User=不存在,或者服务二进制文件丢失)。如果设置为forking,则使用ExecStart=配置的进程将调用fork()作为其启动过程的一部分。当启动完成并设置所有通信通道时,预期父进程将退出。子进程继续作为主服务进程运行,服务管理器将考虑在父进程退出时启动该单元。这是传统UNIX服务的行为。如果使用此设置,建议也使用PIDFile=选项,以便systemd能够可靠地识别服务的主要进程。系统d将在父进程退出后立即启动后续单元。
您的流程显然不是分叉过程,您尝试过多个黑客攻击,以便在systemd本机支持的情况下使其成为一个。
PIDFile=采用引用服务的PID文件的路径。对于将Type=设置为forking的服务,建议使用此选项。指定的路径通常指向/run/下面的文件。如果指定了相对路径,则以/run/作为前缀。服务管理器将在服务启动后从该文件读取服务主进程的PID。服务管理器不会写入在这里配置的文件,但如果服务仍然存在,它将在服务关闭后删除该文件。PID文件不需要由特权用户拥有,但是如果它是由非特权用户拥有的,则执行附加的安全限制:该文件可能不是其他用户拥有的文件的符号链接(既不直接也不是间接的),并且PID文件必须引用已经属于该服务的进程。
您正在将systemd MAINPID变量写入该文件,但是不仅MAINPID没有为ExecStartPost=编写文档,而且更重要的是,由于设置了PIDFile,它实际上是从该文件中读取的(此时,我不太确定它扩展到了什么,因为在这种情况下,它没有任何意义;当ExecStart=返回时应该读取它,所以我认为它是空的)。
本节描述命令行解析以及
ExecStart=、ExecStartPre=、ExecStartPost=、ExecReload=、ExecStop=和ExecStopPost=选项的变量和说明符替换。<...>这种语法是受shell语法启发的,但是只理解以下段落中描述的元字符和扩展,并且变量的扩展是不同的。具体来说,不支持使用"<“、"<<”、">“和">>”的重定向、使用“not”的管道、使用"&“在后台运行程序以及其他shell语法元素。
您的ExecStart=和ExecRestart=除了在Type=和ExecRestart=的默认实现方面是没有意义的之外,显然是坏的。
到目前为止,bash包装器是无用的,根据它的目标,您应该完全删除它,并将UT服务器直接设置为ExecStart=参数。服务器命令行可以从EnvironmentFile=中获取,您就完成了!
此外,除非该服务器是一个绝对的噩梦,使用SIGKILL停止任何类型的服务都是.至少可以说是坏的。ExecStop=的默认实现可能更适合。
下次编写服务脚本时,尝试从默认脚本开始,逐步更改参数,而不是更改所有参数,然后想知道20个参数中哪一个被破坏了,就更容易调试了
https://serverfault.com/questions/1022186
复制相似问题