如何使用 systemd 在啟動時運行 Linux 程序

已發表: 2022-01-29
筆記本電腦上的程式化終端窗口。
Fatmawati Achmad Zaenuri/Shutterstock

需要在啟動時啟動 Linux 程序? systemd 軟件提供了一種在任何帶有 systemd 的 Linux 發行版上執行此操作的方法——現在大多數 Linux 發行版,包括 Ubuntu。 我們將引導您完成創建集成服務的過程——它甚至會與期刊對話。

本教程演示如何設置在您啟動系統時啟動的系統服務。 要在登錄時啟動圖形程序,請改用桌面的啟動管理器。

在啟動時運行程序

有時,您安裝在計算機上的軟件會將自己掛接到 Linux 啟動過程中,這樣每次啟動計算機時程序都會自動啟動。 您可以使用自己的程序和腳本,或者實際上是您計算機上的任何其他程序,輕鬆實現相同的行為。

啟動時啟動的程序由systemd 、系統和服務管理器控制。 systemd是啟動時運行的第一個進程。 它始終具有進程 ID (PID) 1。在您的計算機中運行的每個其他進程都由systemd啟動,或者由systemd已經啟動的進程啟動。

在後台運行的程序稱為守護程序或服務。 systemd末尾的“d”代表守護進程。 在本文中,我們將創建一個示例服務。 要勾選所有方框,我們的服務必須是:

  • 通過服務單元文件與systemd集成
  • 在啟動時啟動
  • 可使用systemctl控制, systemd的控制接口
  • 能寫日記

創建服務程序

我們需要有一個systemd將啟動的程序。 我們將創建一個名為“htg.sh”的簡單腳本。 本教程使用 Gedit 文本編輯器,但您可以使用您喜歡的任何文本編輯器。

 觸摸htg.sh
 gedit htg.sh 

廣告

gedit編輯器將打開。 將以下文本複制並粘貼到編輯器中。

 #!/bin/bash

echo "htg.service: ## 開始 ##" | systemd-cat -p 信息

儘管 :
做
TIMESTAMP=$(日期 '+%Y-%m-%d %H:%M:%S')
echo "htg.service: 時間戳 ${TIMESTAMP}" | systemd-cat -p 信息
睡覺 60
完畢

保存更改並關閉編輯器。

gedit 編輯器中的 htg.sh 腳本

該腳本並沒有做很多事情,但有幾點值得注意。

  • 兩條echo顯線通過systemd-cat管道傳輸,該程序從程序獲取輸出並將其發送到日誌。 期刊的條目被優先考慮。 我們使用-p (優先級)選項來指示我們的消息僅用於信息(信息)。 它們不是重要的錯誤或警告。
  • 有一個無限的while循環。
  • TIMESTAMP變量設置為當前日期和時間。 這被格式化為消息並發送到日誌。
  • 然後腳本休眠 60 秒。
  • 60 秒後重複循環。 因此,此腳本每分鐘向日誌寫入一次帶時間戳的消息。

我們將腳本複製到/usr/local/bin目錄。

 sudo cp htg.sh /usr/local/bin 

我們需要讓它可執行:

 sudo chmod +x /usr/local/bin/htg.sh 

創建服務單元文件

systemd啟動的每個程序都有一個定義文件,稱為服務單元文件。 這包含systemd可以用來定位和啟動程序以及定義其某些行為的某些屬性。

我們需要為我們的新服務創建一個單元文件,但謹慎的做法是確保所有現有的單元文件都沒有我們想要為我們的新服務提供的名稱。

 sudo systemctl list-unit-files --type-service 

您可以滾動瀏覽按字母順序排序的單元文件列表,並檢查您要使用的名稱是否未被佔用。

廣告

我們的服務將被稱為“htg.service”。 沒有單元文件具有該名稱,因此我們可以繼續並創建我們的單元文件。

 sudo gedit /etc/systemd/system/htg.service 

gedit編輯器將打開。 將以下文本複制並粘貼到編輯器中:

 [單元]
描述=How-To Geek 服務示例

想要=network.target
After=syslog.target network-online.target

[服務]
類型=簡單
ExecStart=/usr/local/bin/htg.sh
重啟=失敗
重啟秒=10
KillMode=進程

[安裝]
WantedBy=多用戶.target

保存更改並關閉編輯器。

gedit 編輯器中的 htg.service 單元文件

這些條目具有這些含義。 這些是典型的條目。 我們簡單的服務實際上並不需要它們中的大部分,但是包括它們可以讓我們解釋它們。

  • 描述:這是您的服務的文本描述。
  • Wants:我們的服務想要——但不要求——在我們的服務啟動之前網絡已經啟動。
  • 之後:在此服務成功啟動後應啟動的單元名稱列表(如果它們尚未運行)。
  • 類型:簡單。 一旦ExecStart指定的進程被派生, systemd將認為該服務已啟動。
  • ExecStart:應該啟動的進程的路徑。
  • 重新啟動:何時以及是否應該重新啟動服務。 我們已將其設置為“失敗時”。
  • RestartSec:在嘗試重新啟動服務之前等待多長時間。 該值以秒為單位。
  • KillMode:定義如果我們要求systemctl停止服務, systemd應該如何殺死進程。 我們將此設置為“處理”。 這導致systemd僅在主進程上使用SIGTERM信號。 如果我們的服務是一個重要的程序而不是一個簡單的腳本,我們會將其設置為“混合”以確保任何衍生的進程也被終止。
  • WantedBy:我們將此設置為“multi-user.target”,這意味著只要係統處於多個用戶可以登錄的狀態,無論圖形用戶界面是否可用,都應該啟動服務。

單元文件不需要是可執行的,但是單元文件的權限應該限制誰可以編輯它。 您不希望惡意或惡作劇的用戶更改單元文件,以便它完全執行不同的程序。

該命令將授予所有者讀寫權限,以及對組的讀取權限。 其他人將沒有權限。

 sudo chmod 640 /etc/systemd/system/htg.service 

即使服務尚未運行,我們也可以讓systemctl為我們檢查單元文件的語法。 任何錯誤都會被報告。 (實際上,“.service”部分對於大多數命令是可選的。)

 systemctl 狀態 htg.service 

廣告

沒有突出顯示錯誤,這意味著我們的單元文件在語法上是正確的。

啟動服務

當您添加新的單元文件或編輯現有的單元文件時,您必須告訴systemd重新加載單元文件定義。

 sudo systemctl daemon-reload

如果您希望在啟動時啟動服務,則必須啟用它:

 sudo systemctl 啟用 htg

啟用服務不會啟動它,它只會將其設置為在啟動時啟動。 要立即啟動服務,您必須使用帶有start選項的systemctl

 sudo systemctl start htg 

驗證服務

手動啟動服務或重啟電腦後,我們可以驗證我們的服務是否正常運行。

 sudo systemctl status htg.service 

為我們顯示服務的狀態。

終端窗口中 htg.service 的狀態

  • 綠點表示我們的服務正常運行。
  • 服務的名稱是“htg.service”,長描述是我們在單元文件中提供的。
  • 我們顯示了哪個單元文件已加載“/etc/systemd/system/htg.service”。
  • 該服務處於活動狀態,並為我們列出了該服務的啟動時間。
  • 它的PID是7762。
  • 有兩個與服務相關的任務。
  • 該服務總共使用了 928 Kibibytes 的內存。
  • 控制組包括“htg.sh”腳本和由“htg.sh”啟動的sleep命令。 大多數時候, sleep命令會為這個服務工作。

我們還顯示了此服務生成的最後 10 個日記帳分錄。 不出所料,它們都相隔一分鐘。

停止和禁用服務

如果需要停止服務,可以使用以下命令:

 sudo systemctl stop htg.service 

廣告

這會停止服務,但不會阻止它在下次重新啟動計算機時重新啟動。 要停止在啟動時啟動的服務,您需要禁用它:

 sudo systemctl 禁用 htg.service 

如果服務正在運行,此命令不會停止它。 它只是告訴systemd在下次重新啟動時不要啟動該服務。

如果要停止服務並阻止它在啟動時啟動,請使用這兩個命令。

服務提示

在嘗試將其作為服務啟動之前,請確保您的程序按預期運行。

相關:適合開發人員和愛好者的最佳 Linux 筆記本電腦