1. 程式人生 > >centos7編寫自己的服務,執行systemctl後卡住了(即shell阻塞了)

centos7編寫自己的服務,執行systemctl後卡住了(即shell阻塞了)

問題:

今天在寫centos7的systemctl 服務是,遇到一個坑,表現為當我執行systemctl命令後shell阻塞在那裡,沒有像平時執行命令那樣自動結束(只能自己按Ctrl+C強制結束),效果如下:


強制結束後,檢視程式發現目標程式啟動是成功的, 但狀態為activating (start)而不是activating (running)態:


hello.service服務程式碼如下:

[Unit]
Description=Hello service

[Service]
Type=forking
User=root
Group=root
ExecStart=/usr/bin/python /root/hello.py
Restart=always

[Install]
WantedBy=multi-user.target

hello.py程式碼為:

#coding:utf-8
import time

while True:
    time.sleep(5)

解決方法:

導致此問題的原因是:hello.service型別選擇有問題, 不應該選forking型別;型別改為Type=simple(或刪除Type=forking這句),問題便得到解決。

出現這個問題的可能原因,先看看type的種類和解釋:

Type=oneshot這一選項適用於只執行一項任務、隨後立即退出的服務。可能需要同時設定 RemainAfterExit=yes 使得 systemd 在服務程序退出之後仍然認為服務處於啟用狀態。
Type=notify 與 Type=simple 相同,但約定服務會在就緒後向 systemd 傳送一個訊號。這一通知的實現由 libsystemd-daemon.so 提供。
Type=dbus若以此方式啟動,當指定的 BusName 出現在DBus系統總線上時,systemd認為服務就緒。
Type=idlesystemd會等待所有任務處理完成後,才開始執行 idle 型別的單元。其他行為與 Type=simple 類似。
Type=forkingsystemd認為當該服務程序fork,且父程序退出後服務啟動成功。對於常規的守護程序(daemon),除非你確定此啟動方式無法滿足需求,使用此型別啟動即可。使用此啟動型別應同時指定 PIDFile=,以便 systemd 能夠跟蹤服務的主程序
Type=simple(預設值) systemd認為該服務將立即啟動。服務程序不會 fork 。如果該服務要啟動其他服務,不要使用此型別啟動,除非該服務是socket 啟用型。
從上表可以看到,當型別為forking時,systemd會認為所運行當該服務本身是守護程序即本身會fork,且只有父程序退出後systemd才會退出,但由於參考例子並不是守護程序,故systemd一直處於阻塞等待狀態,預設的simple無等待這一環節。