Systemd:啟動後單元文件超時
我寫了一個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 上有一些東西?這只是好奇..
這主要是從systemd.service 文件中複製粘貼,因為它在很大程度上已經足夠了。
Type=
<…>
exec
類型類似於,但服務管理器會認為該simple
單元在主服務二進製文件執行後立即啟動。服務經理將延遲後續單位的啟動,直到該時間點。(或者換句話說:在返回simple
後立即繼續執行進一步的作業,而在兩者和服務程序成功之前不會繼續。)請注意,這意味著systemctl start服務的命令行將在無法成功呼叫服務的二進製文件時報告失敗(例如因為所選內容不存在,或者服務二進製文件失去)。fork()``exec``fork()``execve()``exec``User=
如果設置為
forking
,則預計配置為的程序ExecStart=
將fork()
作為其啟動的一部分進行呼叫。當啟動完成並設置所有通信通道時,父程序將退出。子程序作為主服務程序繼續執行,當父程序退出時服務管理器會認為該單元啟動。這是傳統 UNIX 服務的行為。如果使用此設置,建議也使用該PIDFile=
選項,以便 systemd 能夠可靠地辨識服務的主程序。一旦父程序退出,systemd 將繼續啟動後續單元。你的程序顯然不是一個分叉程序,當它被 systemd 原生支持時,你已經嘗試了多次黑客攻擊以使其成為一個。
PIDFile=
採用引用服務 PID 文件的路徑。
Type=
對於設置為 的服務,建議使用此選項forking
。指定的路徑通常指向下面的文件/run/
。如果指定了相對路徑,則前綴為/run/
. 服務啟動後,服務管理器會從這個文件中讀取服務主程序的PID。服務管理器不會寫入此處配置的文件,但如果該文件仍然存在,它會在服務關閉後刪除該文件。PID 文件不需要由特權使用者擁有,但如果它由非特權使用者擁有,則強制執行額外的安全限制:該文件可能不是指向其他使用者擁有的文件的符號連結(直接或間接) ,並且 PID 文件必須引用已經屬於該服務的程序。您正在將 systemd
MAINPID
變數寫入該文件,但不僅MAINPID
沒有記錄,ExecStartPost=
而且更重要的是,由於PIDFile
已設置,它實際上是從該文件中讀取的(此時,我不太確定它擴展為什麼,因為在這個情況,這沒有任何意義;它應該在ExecStart=
返回時被讀取,所以我會說它是空的)。
ExecStart=
本節介紹命令行解析以及,ExecStartPre=
,ExecStartPost=
,ExecReload=
,ExecStop=
, 和ExecStopPost=
選項的變數和說明符替換。<…>
這種語法是受shell語法啟發的,但只理解後面幾段描述的元字元和擴展,變數的擴展是不同的。具體來說,不支持使用“<”、“<<”、“>”和“>>”進行重定向、使用“|”進行管道、使用“&”在後台執行程序以及其他 shell 語法元素。
除了對. _
ExecStart=
_ExecRestart=``Type=``ExecRestart=
到目前為止,您的 bash 包裝器是無用的,根據它的目的,您應該完全刪除它並直接將 UT 伺服器設置為
ExecStart=
參數。伺服器命令行可以來自一個EnvironmentFile=
,你就完成了!此外,除非該伺服器絕對是一場噩夢,否則使用 SIGKILL 停止任何類型的服務都是……糟糕,至少可以這麼說。的預設實現
ExecStop=
可能更適合。下次編寫服務腳本時,嘗試從預設的開始,逐步更改參數,而不是更改所有參數,然後想知道二十個參數中的哪一個壞了,調試起來更容易😉