日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CentOS 7之Systemd详解之服务单元设置system.service

發(fā)布時間:2023/12/9 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CentOS 7之Systemd详解之服务单元设置system.service 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

英文網(wǎng)址:https://www.freedesktop.org/software/systemd/man/systemd.service.html

?

名稱

systemd.service - 服務(wù)單元配置

概要

service.service

描述

以 .service 結(jié)尾的單元文件,用于封裝一個被 systemd 監(jiān)視與控制的進(jìn)程。

本手冊只列出專用于此種單元的選項(xiàng),它們?nèi)课挥?#34;[Service]"小節(jié)之中(通用于所有單元的選項(xiàng)參見 systemd.unit(5) 手冊)。

其他可用的選項(xiàng)位于 systemd.exec(5) 手冊(定義了命令的執(zhí)行環(huán)境), 以及 systemd.kill(5) 手冊(定義了如何結(jié)束進(jìn)程), 以及 systemd.resource-control(5) 手冊(定義了進(jìn)程的資源控制)。

如果要求啟動或停止的某個單元文件不存在,systemd 將會尋找同名的SysV初始化腳本(去掉 .service 后綴), 并根據(jù)那個同名腳本動態(tài)的創(chuàng)建一個 service 單元。這主要用于與傳統(tǒng)的SysV兼容(不能保證100%兼容)。 更多與SysV的兼容性可參見 Incompatibilities with SysV 文檔。

自動依賴

  • 設(shè)置了 Type=dbus 的服務(wù)會自動添加 Requires=dbus.socket 與 After=dbus.socket 依賴
  • 基于套接字激活的服務(wù)會自動添加對與其相關(guān)的 .socket 單元的 After= 依賴。

除非明確設(shè)置了 DefaultDependencies=false,否則 service 單元都自動隱含如下依賴:

  • Requires=sysinit.target After=sysinit.target After=basic.target Conflicts=shutdown.target Before=shutdown.target 這樣可以確保普通的服務(wù)單元:(1)、在基礎(chǔ)系統(tǒng)啟動完畢之后才開始啟動,(2)、在關(guān)閉系統(tǒng)之前先被干凈的停止。 只有那些需要在系統(tǒng)啟動的早期就必須啟動的服務(wù),以及那些必須在關(guān)機(jī)動作的結(jié)尾才能停止的服務(wù)才需要設(shè)置 DefaultDependencies=false 。 systemd.exec(5) 與 systemd.resource-control(5) 中的某些資源限制選項(xiàng)也會自動隱含的添加一些其他的依賴關(guān)系。
  • 從同一個模版實(shí)例化出來的所有服務(wù)單元(單元名稱中帶有 "@" 字符), 默認(rèn)全部屬于與模版同名的同一個 slice 單元。 該同名 slice 一般在系統(tǒng)關(guān)機(jī)時,與所有模版實(shí)例一起停止。 如果你不希望像上面這樣,那么可以在模版單元中明確設(shè)置 DefaultDependencies=no , 并且:要么在該模版文件中明確定義特定的 slice 單元(同樣也要明確設(shè)置 DefaultDependencies=no)、 要么在該模版文件中明確設(shè)置 Slice=system.slice (或其他合適的 slice)。

[Service]小節(jié)選項(xiàng)

每個服務(wù)單元文件都必須包含一個"[Service]"小節(jié)。由于此小節(jié)中的許多選項(xiàng)也同時適用于其他類型的單元, 所以本手冊僅記錄了專用于服務(wù)單元的選項(xiàng)。其他共享的選項(xiàng)參見 systemd.exec(5) 與 systemd.kill(5) 手冊。

Type=

  • 設(shè)置進(jìn)程的啟動類型,必須是下列值之一:simple, forking, oneshot, dbus, notify, idle 之一。
  • 如果設(shè)為"simple"(設(shè)置了 ExecStart= 但未設(shè)置 BusName= 時的默認(rèn)值),那么表示 ExecStart= 所設(shè)定的進(jìn)程就是該服務(wù)的主進(jìn)程。 如果此進(jìn)程需要為其他進(jìn)程提供服務(wù),那么必須在該進(jìn)程啟動之前先建立好通信渠道(例如套接字),以加快后繼單元的啟動速度。
  • "dbus"(設(shè)置了 ExecStart= 與 BusName= 時的默認(rèn)值)與"simple"類似,不同之處在于該進(jìn)程需要在 D-Bus 上獲得一個由 BusName= 指定的名稱。 systemd 將會在啟動后繼單元之前,首先確保該進(jìn)程已經(jīng)成功的獲取了指定的 D-Bus 名稱。設(shè)置為此類型相當(dāng)于隱含的依賴于 dbus.socket 單元。
  • "oneshot"(未設(shè)置 ExecStart= 時的默認(rèn)值)與"simple"類似,不同之處在于該進(jìn)程必須在 systemd 啟動后繼單元之前退出。 此種類型通常需要設(shè)置 RemainAfterExit= 選項(xiàng)。
  • 如果設(shè)為"forking",那么表示 ExecStart= 所設(shè)定的進(jìn)程將會在啟動過程中使用 fork() 系統(tǒng)調(diào)用。這是傳統(tǒng)UNIX守護(hù)進(jìn)程的經(jīng)典做法。 也就是當(dāng)所有的通信渠道都已建好、啟動亦已成功之后,父進(jìn)程將會退出,而子進(jìn)程將作為該服務(wù)的主進(jìn)程繼續(xù)運(yùn)行。 對于此種進(jìn)程,建議同時設(shè)置 PIDFile= 選項(xiàng),以幫助 systemd 準(zhǔn)確定位該服務(wù)的主進(jìn)程,進(jìn)而加快后繼單元的啟動速度。
  • "notify"與"simple"類似,不同之處在于該進(jìn)程將會在啟動完成之后通過 sd_notify(3) 之類的接口發(fā)送一個通知消息。 systemd 將會在啟動后繼單元之前,首先確保該進(jìn)程已經(jīng)成功的發(fā)送了這個消息。 如果設(shè)置為此類型,那么 NotifyAccess= 將只能設(shè)置為"all"或者"main"(默認(rèn))。 注意,目前 Type=notify 尚不能在 PrivateNetwork=yes 的情況下正常工作。
  • "idle"與"simple"類似,不同之處在于該進(jìn)程將會被延遲到所有的操作都完成之后再執(zhí)行。 這樣可以避免控制臺上的狀態(tài)信息與 shell 腳本的輸出混雜在一起。

RemainAfterExit=

  • 可設(shè)為"yes"或"no"(默認(rèn)值),表示當(dāng)該服務(wù)的所有進(jìn)程全部退出之后,是否依然將此服務(wù)視為活動(active)狀態(tài)。

GuessMainPID=

  • 可設(shè)為"yes"(默認(rèn)值)或"no",表示在無法明確定位該服務(wù)的主進(jìn)程的情況下,systemd 是否應(yīng)該猜測主進(jìn)程的PID(可能不正確)。 該選項(xiàng)僅在設(shè)置了 Type=forking 但未設(shè)置 PIDFile= 的情況下有意義。如果PID猜測錯誤,那么該服務(wù)的失敗檢測與自動重啟功能將失效。

PIDFile=

  • 守護(hù)進(jìn)程的PID文件,必須是絕對路徑。強(qiáng)烈建議在 Type=forking 的情況下明確設(shè)置此選項(xiàng)。 systemd 將會在此服務(wù)啟動后從此文件中讀取主守護(hù)進(jìn)程的PID 。systemd 不會寫入此文件,但會在此服務(wù)停止后刪除它(若存在)。

BusName=

  • 設(shè)置與此服務(wù)通信所使用的 D-Bus 名稱。在 Type=dbus 的情況下必須明確設(shè)置此選項(xiàng)。

BusPolicy=

  • 如果設(shè)置了此項(xiàng),那么 systemd 將會創(chuàng)建一個自定義的kdbus端點(diǎn)(endpoint),并將其安裝為該服務(wù)默認(rèn)的總線節(jié)點(diǎn)(bus node)。 這個自定義的端點(diǎn)可以擁有它自己的策略規(guī)則。端點(diǎn)的名稱就是其所服務(wù)的單元的名稱。 端點(diǎn)的節(jié)點(diǎn)(node)將被綁定掛載到默認(rèn)的總線節(jié)點(diǎn)的位置,這樣該服務(wù)就只能通過它自己的端點(diǎn)訪問總線。 注意,自定義端點(diǎn)的默認(rèn)策略是'拒絕所有',因此,你必須在 BusPolicy= 中明確的添加必要的允許策略。 這個選項(xiàng)的值由兩部分組成:總線名+訪問級別,中間以空格分隔。 訪問級別必須是 see, talk, own 之一,并且 talk 隱含了 see ,而 own 隱含了 talk 與 see 。 如果對同一個總線名稱多次指定了訪問級別,那么將以擁有最大權(quán)限的那個為準(zhǔn)。 例如: BusPolicy=org.freedesktop.systemd1 talk BusPolicy=org.foo.bar see 該選項(xiàng)僅在內(nèi)核開啟了kdbus(即將并入官方內(nèi)核)支持的情況下有意義。

ExecStart=

  • 在啟動該服務(wù)時需要執(zhí)行的命令行(命令+參數(shù))。有關(guān)命令行的更多細(xì)節(jié)可參見后文的"命令行"小節(jié)。 僅在設(shè)置了 Type=oneshot 的情況下,才可以設(shè)置任意個命令行(包括零個),否則必須且只能設(shè)置一個命令行。 多個命令行既可以在同一個 ExecStart= 中設(shè)置,也可以通過設(shè)置多個 ExecStart= 來達(dá)到相同的效果。 如果設(shè)為一個空字符串,那么先前設(shè)置的所有命令行都將被清空。 如果不設(shè)置任何 ExecStart= 指令,那么必須確保設(shè)置了 RemainAfterExit=yes 指令。 命令行必須以一個絕對路徑表示的可執(zhí)行文件開始,并且其后的那些參數(shù)將依次作為"argv[1] argv[2] ..."傳遞給被執(zhí)行的進(jìn)程。 如果在絕對路徑前加上可選的"@"前綴,那么其后的那些參數(shù)將依次作為"argv[0] argv[1] argv[2] ..."傳遞給被執(zhí)行的進(jìn)程。 如果在絕對路徑前加上可選的"-"前綴,那么即使該進(jìn)程以失敗狀態(tài)(例如非零的返回值或者出現(xiàn)異常)退出,也會被視為成功退出。 可以同時使用"-"與"@"前綴,且順序任意。 如果設(shè)置了多個命令行,那么這些命令行將以其在單元文件中出現(xiàn)的順序依次執(zhí)行。 如果某個無"-"前綴的命令行執(zhí)行失敗,那么剩余的命令行將不會被執(zhí)行,同時該單元將變?yōu)槭?failed)狀態(tài)。 當(dāng)未設(shè)置 Type=forking 時,這里設(shè)置的命令行所啟動的進(jìn)程將被視為該服務(wù)的主守護(hù)進(jìn)程。

ExecStartPre=, ExecStartPost=

  • 設(shè)置在執(zhí)行 ExecStart= 之前/后執(zhí)行的命令行。語法規(guī)則與 ExecStart= 完全相同。 如果設(shè)置了多個命令行,那么這些命令行將以其在單元文件中出現(xiàn)的順序依次執(zhí)行。 如果某個無"-"前綴的命令行執(zhí)行失敗,那么剩余的命令行將不會被執(zhí)行,同時該單元將變?yōu)槭?failed)狀態(tài)。 僅在所有無"-"前綴的 ExecStartPre= 命令全部執(zhí)行成功的前提下,才會繼續(xù)執(zhí)行 ExecStart= 命令。 ExecStartPost= 命令僅在服務(wù)已經(jīng)被成功啟動之后才會運(yùn)行,判斷的標(biāo)準(zhǔn)基于 Type= 選項(xiàng)。 具體說來,對于 Type=simple 或 Type=idle 就是主進(jìn)程已經(jīng)成功啟動;對于 Type=oneshot 來說就是主進(jìn)程已經(jīng)成功退出; 對于 Type=forking 來說就是初始進(jìn)程已經(jīng)成功退出;對于 Type=notify 來說就是已經(jīng)發(fā)送了"READY=1"; 對于 Type=dbus 來說就是已經(jīng)取得了 BusName= 中設(shè)置的總線名稱。 注意,不可將 ExecStartPre= 用于需要長時間執(zhí)行的進(jìn)程。 因?yàn)樗杏?ExecStartPre= 派生的子進(jìn)程都會在啟動 ExecStart= 服務(wù)進(jìn)程之前被殺死。

ExecReload=

  • 這是一個可選的指令,用于設(shè)置當(dāng)該服務(wù)被要求重新載入配置時所執(zhí)行的命令行。語法規(guī)則與 ExecStart= 完全相同。 另外,還有一個特殊的環(huán)境變量 $MAINPID 可以用于表示主進(jìn)程的PID,例如可以這樣使用: /bin/kill -HUP $MAINPID 注意,像上例那樣,通過向守護(hù)進(jìn)程發(fā)送復(fù)位信號,強(qiáng)制其重新加載配置文件,并不是一個好習(xí)慣。 因?yàn)檫@是一個異步操作,所以不適用于需要按照特定順序重新加載配置文件的服務(wù)。 我們強(qiáng)烈建議將 ExecReload= 設(shè)置為一個能夠確保重新加載配置文件的操作同步完成的命令行。

ExecStop=

  • 這是一個可選的指令,用于設(shè)置當(dāng)該服務(wù)被要求停止時所執(zhí)行的命令行。語法規(guī)則與 ExecStart= 完全相同。 執(zhí)行完此處設(shè)置的命令行之后,該服務(wù)所有剩余的進(jìn)程將會根據(jù) KillMode= 的設(shè)置被殺死(參見 systemd.kill(5) 手冊)。 如果未設(shè)置此選項(xiàng),那么當(dāng)此服務(wù)被停止時,該服務(wù)的所有進(jìn)程都將會根據(jù) KillMode= 的設(shè)置被立即全部殺死。 與 ExecReload= 一樣,也有一個特殊的環(huán)境變量 $MAINPID 可以用于表示主進(jìn)程的PID 一般來說,僅僅設(shè)置一個結(jié)束服務(wù)的命令,而不等待其完成,是不夠的。 因?yàn)楫?dāng)此處設(shè)置的命令執(zhí)行完之后,剩余的進(jìn)程會被 SIGKILL 信號立即殺死,這可能會導(dǎo)致數(shù)據(jù)丟失。 因此,這里設(shè)置的命令必須是同步操作,而不能是異步操作。

ExecStopPost=

  • 這是一個可選的指令,用于設(shè)置該服務(wù)停止之后所執(zhí)行的命令行。語法規(guī)則與 ExecStart= 完全相同。 無論此服務(wù)是正常停止,還是異常退出,此處的設(shè)置都適用。 RestartSec= 設(shè)定在重啟服務(wù)(Restart=)前暫停多長時間。默認(rèn)值是100毫秒(100ms)。 如果未指定時間單位,那么將視為以秒為單位。例如設(shè)為"20"等價于設(shè)為"20s"。

TimeoutStartSec=

  • 設(shè)定該服務(wù)允許的最大啟動時長。如果守護(hù)進(jìn)程未能在限定的時長內(nèi)發(fā)出"啟動完畢"的信號,那么該服務(wù)將被視為啟動失敗,并會被關(guān)閉。 如果未指定時間單位,那么將視為以秒為單位。例如設(shè)為"20"等價于設(shè)為"20s"。設(shè)為"0"則表示永不超時。 當(dāng) Type=oneshot 時,默認(rèn)值為"0",否則默認(rèn)值等于 DefaultTimeoutStartSec= 的值(參見 systemd-system.conf(5) 手冊)。

TimeoutStopSec=

  • 設(shè)定該服務(wù)允許的最大停止時長。如果該服務(wù)未能在限定的時長內(nèi)成功停止,那么將會被強(qiáng)制使用 SIGTERM 信號關(guān)閉, 如果依然未能在相同的時長內(nèi)成功停止,那么將會被強(qiáng)制使用 SIGKILL 信號關(guān)閉(參見 systemd.kill(5) 手冊中的 KillMode= 選項(xiàng))。 如果未指定時間單位,那么將視為以秒為單位。例如設(shè)為"20"等價于設(shè)為"20s"。設(shè)為"0"則表示永不超時。 默認(rèn)值等于 DefaultTimeoutStartSec= 的值(參見 systemd-system.conf(5) 手冊)。

TimeoutSec=

  • 一個同時設(shè)置 TimeoutStartSec= 與 TimeoutStopSec= 的快捷方式。

WatchdogSec=

設(shè)置該服務(wù)的看門狗(watchdog)的超時時長。看門狗將在服務(wù)成功啟動之后被激活。 該服務(wù)在運(yùn)行過程中必須周期性的以"WATCHDOG=1"("keep-alive ping")調(diào)用 sd_notify(3) 函數(shù)。 如果在兩次調(diào)用之間的時間間隔大于這里設(shè)定的值,那么該服務(wù)將被視為失敗(failed)狀態(tài),并會被強(qiáng)制使用 SIGABRT 信號關(guān)閉。 通過將 Restart= 設(shè)為"on-failure"或"always"可以實(shí)現(xiàn)在失敗狀態(tài)下的自動重啟該服務(wù)。 這里設(shè)置的值將會通過 WATCHDOG_USEC 環(huán)境變量傳遞給守護(hù)進(jìn)程,這樣就允許那些支持看門狗的服務(wù)自動啟用"keep-alive ping"。 如果設(shè)置了此選項(xiàng),那么必須將 NotifyAccess= 設(shè)為"main"(此種情況下的隱含默認(rèn)值)或"all"。 如果未指定時間單位,那么將視為以秒為單位。例如設(shè)為"20"等價于設(shè)為"20s"。默認(rèn)值"0"表示禁用看門狗功能。

Restart=

  • 當(dāng)服務(wù)進(jìn)程正常退出、異常退出、被殺死、超時的時候,是否重新啟動該服務(wù)。 "服務(wù)進(jìn)程"是指 ExecStart=, ExecStartPre=, ExecStartPost=, ExecStop=, ExecStopPost=, ExecReload= 中設(shè)置的進(jìn)程。 當(dāng)進(jìn)程是由于 systemd 的正常操作(例如 systemctl stop|restart)而被停止時,該服務(wù)不會被重新啟動。 "超時"可以是看門狗的"keep-alive ping"超時,也可以是 systemctl start|reload|stop 操作超時。
  • 該選項(xiàng)可以取下列值之一:no, on-success, on-failure, on-abnormal, on-watchdog, on-abort, always "no"(默認(rèn)值)表示不會被重啟。"always"表示會被無條件的重啟。 "on-success"表示僅在服務(wù)進(jìn)程正常退出時重啟,所謂"正常退出"是指: 退出碼為"0",或者進(jìn)程收到 SIGHUP, SIGINT, SIGTERM, SIGPIPE 信號并且退出碼符合 SuccessExitStatus= 的設(shè)置。 "on-failure"表示僅在服務(wù)進(jìn)程異常退出時重啟,所謂"異常退出"是指: 退出碼不為"0",或者進(jìn)程被強(qiáng)制殺死(包括"core dump"以及收到 SIGHUP, SIGINT, SIGTERM, SIGPIPE 之外的其他信號), 或者進(jìn)程由于看門狗或者 systemd 的操作超時而被殺死。 對于 on-failure, on-abnormal, on-abort, on-watchdog 的分別適用于哪種異常退出,見下表:

??????

  • 注意如下兩個例外情況: (1) RestartPreventExitStatus= 中列出的退出碼或者信號永遠(yuǎn)不會導(dǎo)致該服務(wù)被重啟。 (2) RestartForceExitStatus= 中列出的退出碼或者信號將會無條件的導(dǎo)致該服務(wù)被重啟。 對于需要長期持續(xù)運(yùn)行的守護(hù)進(jìn)程,推薦設(shè)為"on-failure"以增強(qiáng)可用性。 對于自身可以自主選擇何時退出的服務(wù),推薦設(shè)為"on-abnormal"。

SuccessExitStatus=

  • 額外定義附加的進(jìn)程"正常退出"狀態(tài)。可以設(shè)為一系列以空格分隔的數(shù)字退出碼或者信號名稱,例如: SuccessExitStatus=1 2 8 SIGKILL 表示當(dāng)進(jìn)程的退出碼是 1, 2, 8 或被 SIGKILL 信號終止時,都可以視為"正常退出"。 注意,退出碼"0"以及 SIGHUP, SIGINT, SIGTERM, SIGPIPE 信號是標(biāo)準(zhǔn)的"正常退出",不需要在此特別定義。 注意,如果進(jìn)程擁有自定義的信號處理器,并且在收到信號后通過調(diào)用 _exit(2) 退出,那么有關(guān)信號的信息就會丟失。 在這種情況下,進(jìn)程必須自己完成清理工作并使用相同的信號自殺。參見 Proper handling of SIGINT/SIGQUIT — How to be a proper program 如果多次使用此選項(xiàng),那么最終的結(jié)果將是多個列表的合集。如果將此項(xiàng)設(shè)為空,那么先前設(shè)置的列表將被清空。

RestartPreventExitStatus=

  • 可以設(shè)為一系列以空格分隔的數(shù)字退出碼或者信號名稱,當(dāng)進(jìn)程的退出碼或收到的信號與此處的設(shè)置匹配時, 該服務(wù)將無條件的禁止重新啟動(無視 Restart= 的設(shè)置)。例如: RestartPreventExitStatus=1 6 SIGABRT 表示退出碼 1, 2, 8 與 SIGKILL 信號將不會導(dǎo)致該服務(wù)被重啟。 默認(rèn)值為空,表示完全遵守 Restart= 的設(shè)置。
  • 如果多次使用此選項(xiàng),那么最終的結(jié)果將是多個列表的合集。如果將此項(xiàng)設(shè)為空,那么先前設(shè)置的列表將被清空。 RestartForceExitStatus= 可以設(shè)為一系列以空格分隔的數(shù)字退出碼或者信號名稱,當(dāng)進(jìn)程的退出碼或收到的信號與此處的設(shè)置匹配時, 該服務(wù)將無條件的被重新啟動(無視 Restart= 的設(shè)置)。 默認(rèn)值為空,表示完全遵守 Restart= 的設(shè)置。 如果多次使用此選項(xiàng),那么最終的結(jié)果將是多個列表的合集。如果將此項(xiàng)設(shè)為空,那么先前設(shè)置的列表將被清空。

PermissionsStartOnly=

  • 設(shè)為 true 表示所有與權(quán)限相關(guān)的執(zhí)行選項(xiàng)(例如 User= 之類的選項(xiàng),參見 systemd.exec(5) 手冊)僅對 ExecStart= 中的程序有效, 而對 ExecStartPre=, ExecStartPost=, ExecReload=, ExecStop=, ExecStopPost= 中的程序無效。 默認(rèn)值 false 表示所有與權(quán)限相關(guān)的執(zhí)行選項(xiàng)對所有 Exec*= 系列選項(xiàng)中的程序都有效。

RootDirectoryStartOnly=

  • 設(shè)為 true 表示根目錄(參見 systemd.exec(5) 中的 RootDirectory= 選項(xiàng))僅對 ExecStart= 中的程序有效, 而對 ExecStartPre=, ExecStartPost=, ExecReload=, ExecStop=, ExecStopPost= 中的程序無效。 默認(rèn)值 false 表示根目錄對所有 Exec*= 系列選項(xiàng)中的程序都有效。

NonBlocking=

  • 是否為所有通過socket激活傳遞的文件描述符設(shè)置非阻塞標(biāo)記(O_NONBLOCK)。默認(rèn)值為 false 設(shè)為 true 表示所有大于2的文件描述符(也就是 stdin, stdout, stderr 之外的文件描述符)都將被設(shè)置為非阻塞模式。 該選項(xiàng)僅在與 socket 單元(systemd.socket(5))聯(lián)用的時候才有意義。

NotifyAccess=

  • 設(shè)置通過sd_notify(3)訪問服務(wù)狀態(tài)通知socket的訪問模式。 可以設(shè)為:none(默認(rèn)值), main, all 之一。 "none"表示不更新任何守護(hù)進(jìn)程的狀態(tài),忽略所有的狀態(tài)更新消息。 "main"表示僅接受主進(jìn)程的狀態(tài)更新消息。 "all"表示接受該服務(wù)cgroup內(nèi)的所有進(jìn)程的狀態(tài)更新消息。 當(dāng)設(shè)置了 Type=notify 或 WatchdogSec= 的時候,此選項(xiàng)應(yīng)該被設(shè)為"main"或"all",如果未設(shè)置,那么隱含為"main"。

Sockets=

  • 設(shè)置一個socket單元的名稱,表示該服務(wù)在啟動時應(yīng)當(dāng)從它繼承socket文件描述符。通常并不需要明確設(shè)置此選項(xiàng), 因?yàn)樗信c該服務(wù)同名(不算后綴)的socket單元的socket文件描述符,都會被自動的傳遞給派生進(jìn)程。 注意:(1)同一個socket文件描述符可以被傳遞給多個不同的進(jìn)程(服務(wù))。 (2)當(dāng)socket上有流量進(jìn)入時,被啟動的可能是另一個不同于該服務(wù)的其他服務(wù)。 換句話說就是:socket單元中的 Service= 所指向的服務(wù)單元中的 Sockets= 設(shè)置未必要反向指回去。
  • 如果多次使用此選項(xiàng),那么最終的結(jié)果將是多個socket單元的合集。如果將此項(xiàng)設(shè)為空,那么先前設(shè)置的socket單元的列表將被清空。

StartLimitInterval=, StartLimitBurst=

  • 限制該服務(wù)的啟動頻率。默認(rèn)值是每10秒內(nèi)不得超過5次(StartLimitInterval=10s StartLimitBurst=5)。
  • StartLimitInterval= 的默認(rèn)值等于systemd配置文件中 DefaultStartLimitInterval= 的值,"0"表示取消啟動頻率限制。
  • StartLimitBurst= 的默認(rèn)值等于systemd配置文件中 DefaultStartLimitBurst= 的值。
  • 雖然這兩個選項(xiàng)經(jīng)常與 Restart= 一起使用,但是它們不只限制 Restart= 羅輯所導(dǎo)致的重啟,而是限制所有類型的啟動(包括手動啟動)。 注意,當(dāng) Restart=邏輯所導(dǎo)致的重啟超出了啟動頻率限制之后,Restart= 邏輯將會被禁用(也就是不會在下一個時間段內(nèi)再次嘗試重啟), 然而,如果該單元隨后又被手動重啟,那么 Restart= 羅輯將被再次激活。 注意,"systemctl reset-failed ..."命令會清除該服務(wù)的重啟次數(shù)計(jì)數(shù)器,這通常用于在手動啟動之前清除啟動限制。

StartLimitAction=

  • 設(shè)置到達(dá)啟動頻率限制后觸發(fā)什么動作。 可設(shè)為 none(默認(rèn)值), reboot, reboot-force, reboot-immediate, poweroff, poweroff-force, poweroff-immediate 之一。
  • "none"表示除了禁止再次啟動之外,不觸發(fā)任何動作。
  • "reboot"表示觸發(fā)常規(guī)的系統(tǒng)重啟的動作,相當(dāng)于執(zhí)行"systemctl reboot"命令。
  • "reboot-force"表示觸發(fā)系統(tǒng)的強(qiáng)制重啟動作(強(qiáng)制殺死所有進(jìn)程但不會造成文件系統(tǒng)不一致),相當(dāng)于執(zhí)行"systemctl reboot -f"命令。
  • "reboot-immediate"表示立即調(diào)用內(nèi)核的reboot(2)函數(shù),可能會造成文件系統(tǒng)的數(shù)據(jù)丟失。
  • poweroff, poweroff-force, poweroff-immediate 與對應(yīng)的"reboot*"項(xiàng)含義類似,不同之處僅僅在于是關(guān)機(jī)而不是重啟。

FailureAction=

  • 設(shè)置當(dāng)該服務(wù)進(jìn)入失敗(failed)狀態(tài)時所觸發(fā)的動作。取值范圍與默認(rèn)值都與 StartLimitAction= 完全相同。

RebootArgument=

  • 設(shè)置reboot(2)系統(tǒng)調(diào)用的可選參數(shù),僅用于 StartLimitAction= 與 FailureAction= 的重啟動作。 其作用與"systemctl reboot [arg]"命令中的可選參數(shù)[arg]完全相同。

FileDescriptorStoreMax=

  • 允許在 systemd 中最多為該服務(wù)存儲多少個使用sd_pid_notify_with_fds(3)的"FDSTORE=1"消息的文件描述符,默認(rèn)值為"0"(不存儲)。 用于實(shí)現(xiàn)重啟該服務(wù)而不會丟失其狀態(tài)(前提是該服務(wù)將各種狀態(tài)序列化之后保存在 /run 中,同時將文件描述符交給 systemd 暫存)。 所有被 systemd 暫存的文件描述符都將在該服務(wù)重啟之后交還給該服務(wù)的主進(jìn)程。 所有被 systemd 暫存的文件描述符都將在遇到如下兩種情況時被自動關(guān)閉: (1)收到 POLLHUP 或 POLLERR 信號;(2)該服務(wù)被徹底停止,并且沒有任何剩余的任務(wù)隊(duì)列

USBFunctionDescriptors=

  • 設(shè)為一個包含 USB FunctionFS 描述符的文件路徑,以實(shí)現(xiàn) USB gadget 支持。 僅與配置了 ListenUSBFunction= 的 socket 單元一起使用。該文件的內(nèi)容將被寫入 ep0 文件。 USBFunctionStrings= 設(shè)為一個包含 USB FunctionFS 字符串的文件路徑。 其行為與上面的 USBFunctionDescriptors= 類似。 參見 systemd.exec(5) 與 systemd.kill(5) 手冊頁,以獲取更多其他選項(xiàng)。

命令行

本小節(jié)講解 ExecStart=, ExecStartPre=, ExecStartPost=, ExecReload=, ExecStop=, ExecStopPost= 選項(xiàng)的命令行解析規(guī)則。

僅在設(shè)置了 Type=oneshot 的前提下,才可以設(shè)置多個命令行,且必須用分號(;)將每個命令行隔開(分號自身用"\;"表示)。

例如: ExecStart=/bin/echo one ; /bin/echo "two two" 每個命令行的內(nèi)部以空格分隔,每一項(xiàng)的邊界都可以用單引號或者雙引號進(jìn)行界定。 第一項(xiàng)是要運(yùn)行的命令,隨后的各項(xiàng)則是命令的參數(shù)。 行尾的反斜杠(\)將被視作續(xù)行符,這和bash的續(xù)行語法類似。例如: ExecStart=/bin/echo / >/dev/null & \; \ /bin/ls 的含義是向 /bin/echo 命令傳遞五個參數(shù):"/", ">/dev/null", "&", ";", "/bin/ls". 命令行的語法刻意保持了與shell的相似性,但并不相同。 特別的,重定向(<, <<, >, >)、管道(|)、后臺運(yùn)行(&),以及其他下文未明確提及的符號都不被支持。 第一項(xiàng),要運(yùn)行的命令,必須使用絕對路徑。可以在其中包含空格,但是不可以包含控制字符。 可以在隨后的各項(xiàng)命令參數(shù)中使用 systemd.unit(5) 中描述的"%"系列特殊符號,但不可用于命令自身(第一項(xiàng))。 此外,還可以使用C語言風(fēng)格的轉(zhuǎn)義序列(含義也相同),但只能識別如下符號:\a \b \f \n \r \t \v \\ \" \' \s \xxx \nnn 此外,還支持兩種不同的環(huán)境變量替換方式("${FOO}"與"$FOO")。

下面的兩個例子,將能清除的體現(xiàn)兩者的差別:

例(1):

Environment="ONE=one" 'TWO=two two' ExecStart=/bin/echo $ONE $TWO ${TWO}

這將給 /bin/echo 依次傳遞如下四個參數(shù): "one", "two", "two", "two two"

例(2):

Environment=ONE='one' "TWO='two two' too" THREE=

ExecStart=/bin/echo ${ONE} ${TWO} ${THREE}

ExecStart=/bin/echo $ONE $TWO $THREE

這將給第一個 /bin/echo 依次傳遞如下三個參數(shù): "'one'", "'two two' too", "" 同時給第二個 /bin/echo 依次傳遞如下三個參數(shù): "one", "two two", "too" 具體說來就是: "${FOO}"的內(nèi)容將原封不動的轉(zhuǎn)化為一個單獨(dú)的命令行參數(shù),無論其中是否包含空格與引號,也無論它是否為空。 "$FOO"的內(nèi)容將將原封不動的插入命令行中,但對插入內(nèi)容的解釋卻遵守一般的命令行解析規(guī)則。 此外,如果想要傳遞美元符號($)自身,則必須使用"$$"。而那些無法在替換時確定內(nèi)容的變量將被當(dāng)做空字符串。 注意,不可以在第一項(xiàng)(也就是命令的絕對路徑)中使用變量替換。 這里使用的變量必須首先在 Environment= 或 EnvironmentFile= 中定義。 此外,在systemd.exec(5)手冊的"派生進(jìn)程中的環(huán)境變量"小節(jié)中列出的"靜態(tài)變量"也可以使用。 例如,$USER 就是一個"靜態(tài)變量",但是,$TERM 則不是"靜態(tài)變量"。 注意,這里的命令行并不直接支持shell命令,但是可以通過模仿下面這個變通的方法來實(shí)現(xiàn): ExecStart=/bin/sh -c 'dmesg | tac'

例1. 簡單服務(wù)

下面的單元文件創(chuàng)建了一個運(yùn)行 /usr/sbin/foo-daemon 守護(hù)進(jìn)程的服務(wù)。未設(shè)置的 Type= 等價于默認(rèn)的 Type=simple 執(zhí)行 /usr/sbin/foo-daemon 進(jìn)程之后,systemd 即認(rèn)為該單元已經(jīng)啟動成功。

[Unit]

Description=Foo

[Service]

ExecStart=/usr/sbin/foo-daemon

[Install]

WantedBy=multi-user.target

注意,/usr/sbin/foo-daemon 必須在啟動后持續(xù)運(yùn)行直到服務(wù)被停止。 如果該進(jìn)程只是為了派生守護(hù)進(jìn)程,那么應(yīng)該使用 Type=forking 因?yàn)闆]有設(shè)置 ExecStop= ,所以在停止服務(wù)時,systemd 將會直接向該服務(wù)啟動的所有進(jìn)程發(fā)送 SIGTERM 信號, 若超過指定時間依然存在未被殺死的進(jìn)程,那么將會繼續(xù)發(fā)送 SIGKILL 信號。詳見 systemd.kill(5) 手冊。

默認(rèn)的 Type=simple 并不包含任何通知機(jī)制(例如通知"服務(wù)已完成初始化")。要想使用通知機(jī)制,應(yīng)該將 Type= 設(shè)為其他非默認(rèn)值。 例如:Type=notify 可用于能夠理解 systemd 通知協(xié)議的服務(wù); Type=forking 可用于能將自身切換到后臺的服務(wù); Type=dbus 可用于能夠在完成初始化之后獲得一個 D-Bus 名稱的單元

例2. 一次性服務(wù)

Type=oneshot 用于那些只需要執(zhí)行一次性動作而不需要持久運(yùn)行的單元,例如文件系統(tǒng)檢查或者清理臨時文件。 此類單元,將會在啟動后一直等待指定的動作完成,然后再回到停止?fàn)顟B(tài)。下面是一個執(zhí)行清理動作的單元:

[Unit]

Description=Cleanup old Foo data

[Service]

Type=oneshot ExecStart=/usr/sbin/foo-cleanup

[Install]

WantedBy=multi-user.target

注意,在 /usr/sbin/foo-cleanup 執(zhí)行結(jié)束前,該服務(wù)一直處于'正在啟動中'的狀態(tài),而一旦執(zhí)行結(jié)束, 該服務(wù)又立即變?yōu)?#39;停止'狀態(tài),也就是說,對于 Type=oneshot 類型的服務(wù),不存在'活動'狀態(tài)。 這意味著,如果再一次啟動該服務(wù),將會再一次執(zhí)行該服務(wù)定義的動作。 注意,在時間順序上晚于該服務(wù)的單元,將會一直等到該服務(wù)變成'停止'狀態(tài)后,才會開始啟動。

Type=oneshot 是唯一可以設(shè)置多個 ExecStart= 的服務(wù)類型。多個 ExecStart= 指令將按照它們出現(xiàn)的順序依次執(zhí)行, 一旦遇到錯誤,就會立即停止,不再繼續(xù)執(zhí)行,同時該服務(wù)也將進(jìn)入'失敗'狀態(tài)。

例3. 可停止的一次性服務(wù)

有時候,單元需要執(zhí)行一個程序以完成某個設(shè)置(啟動),然后又需要再執(zhí)行另一個程序以撤消先前的設(shè)置(停止), 而在設(shè)置持續(xù)有效的時段中,該單元應(yīng)該視為處于'活動'狀態(tài),但實(shí)際上并無任何程序在持續(xù)運(yùn)行。 網(wǎng)絡(luò)配置服務(wù)就是一個典型的例子。此外,只能啟動一次(不可多次啟動)的一次性服務(wù),也是一個例子。

可以通過設(shè)置 RemainAfterExit=yes 來滿足這種需求。 在這種情況下,systemd 將會在啟動成功后將該單元視為處于'活動'狀態(tài)(而不是'停止'狀態(tài))。 RemainAfterExit=yes 雖然可以用于所有 Type= 類型,但是主要用于 Type=oneshot 和 Type=simple 類型。 對于 Type=oneshot 類型,systemd 一直等到服務(wù)啟動成功之后,才會將該服務(wù)置于'活動'狀態(tài)。 所以,依賴于該服務(wù)的其他單元必須等待該服務(wù)啟動成功之后,才能啟動。 但是對于 Type=simple 類型,依賴于該服務(wù)的其他單元無需等待,將會和該服務(wù)同時并行啟動。

下面的類似展示了一個簡單的靜態(tài)防火墻服務(wù)(simple-firewall.service):

[Unit]

Description=Simple firewall

[Service]

Type=oneshot

RemainAfterExit=yes

ExecStart=/usr/local/sbin/simple-firewall-start

ExecStop=/usr/local/sbin/simple-firewall-stop

[Install]

WantedBy=multi-user.target

因?yàn)榉?wù)啟動成功后一直處于'活動'狀態(tài),所以再次執(zhí)行"systemctl start simple-firewall.service"命令不會有任何效果。

例4. 傳統(tǒng)的服務(wù)

多數(shù)傳統(tǒng)的守護(hù)進(jìn)程(服務(wù))在啟動時會轉(zhuǎn)入后臺運(yùn)行。systemd 通過 Type=forking 來支持這種工作方式。 對于 Type=forking 類型的服務(wù),如果最初啟動的進(jìn)程尚未退出,那么該單元將依然處于'正在初始化中'狀態(tài)。 當(dāng)最初的進(jìn)程成功退出,并且至少有一個進(jìn)程仍然在運(yùn)行(并且 RemainAfterExit=no),該服務(wù)才被視為處于'活動'狀態(tài)。

對于單進(jìn)程的傳統(tǒng)服務(wù),當(dāng)最初的進(jìn)程成功退出后,將會只剩單獨(dú)一個進(jìn)程仍然在持續(xù)運(yùn)行, systemd 將會把這個唯一剩余的進(jìn)程視為該服務(wù)的主進(jìn)程。 僅在這種情況下,才將可以在 ExecReload=, ExecStop= ... 之類的選項(xiàng)中使用 $MAINPID 變量。 對于多進(jìn)程的傳統(tǒng)服務(wù),當(dāng)最初的進(jìn)程成功退出后,將會剩余多個進(jìn)程在持續(xù)運(yùn)行, 因此,systemd 無法確定哪一個進(jìn)程才是該服務(wù)的主進(jìn)程。在這種情況下,不可以使用 $MAINPID 變量。

然而,如果主進(jìn)程會創(chuàng)建傳統(tǒng)的PID文件,那么應(yīng)該將 PIDFile= 設(shè)為此PID文件的絕對路徑, 以幫助 systemd 從該P(yáng)ID文件中讀取主進(jìn)程的PID,從而幫助確定該服務(wù)的主進(jìn)程。 注意,守護(hù)進(jìn)程必須在完成初始化之前寫入PID文件,否則可能會導(dǎo)致 systemd 讀取失敗(讀取時文件不存在)。

下面是一個單進(jìn)程傳統(tǒng)服務(wù)的示例:

[Unit]

Description=Some simple daemon

[Service]

Type=forking

ExecStart=/usr/sbin/my-simple-daemon -d

[Install]

WantedBy=multi-user.target

參見 systemd.kill(5) 以了解如何結(jié)束服務(wù)進(jìn)程。

?

例5. D-Bus 服務(wù)

對于需要在 D-Bus 系統(tǒng)總線上注冊一個名字的服務(wù),應(yīng)該使用 Type=dbus 并且設(shè)置相應(yīng)的 BusName= 值。 該服務(wù)不可以派生任何子進(jìn)程。一旦從 D-Bus 系統(tǒng)總線成功獲取所需的名字,該服務(wù)即被視為初始化成功。

下面是一個典型的 D-Bus 服務(wù):

[Unit]

Description=Simple DBus service

[Service]

Type=dbus

BusName=org.example.simple-dbus-service

ExecStart=/usr/sbin/simple-dbus-service

[Install]

WantedBy=multi-user.target

對于用于 D-Bus 激活的服務(wù)來說,不可以包含"[Install]"小節(jié), 而是應(yīng)該在對應(yīng)的 D-Bus service 文件中設(shè)置 SystemdService= 選項(xiàng), 例如(/usr/share/dbus-1/system-services/org.example.simple-dbus-service.service):

[D-BUS Service]

Name=org.example.simple-dbus-service

Exec=/usr/sbin/simple-dbus-service

User=root

SystemdService=simple-dbus-service.service

參見system-kill手冊以了解如何結(jié)束服務(wù)。

例6. 能夠通知初始化已完成的服務(wù)

Type=simple 類型的服務(wù)非常容易編寫,但是無法將'初始化已完成'的消息及時通知給 systemd 是一個重大缺陷。 Type=notify 可以彌補(bǔ)該缺陷,它支持將'初始化已完成'的消息及時通知給 systemd。

下面是一個典型的例子:

[Unit]

Description=Simple notifying service

[Service]

Type=notify

ExecStart=/usr/sbin/simple-notifying-service

[Install]

WantedBy=multi-user.target

注意,該守護(hù)進(jìn)程必須支持 systemd 通知協(xié)議,否則 systemd 將會認(rèn)為該服務(wù)一直處于'正在啟動中',并在超時后將其殺死。 關(guān)于如何支持該通知協(xié)議,參見 sd_notify(3) 手冊頁。 參見 systemd.kill(5) 手冊以了解如何結(jié)束服務(wù)。

總結(jié)

以上是生活随笔為你收集整理的CentOS 7之Systemd详解之服务单元设置system.service的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。