1. 程式人生 > 其它 >8 開機啟動指令碼_在 Ubuntu 上使用 systemd 配置開機執行指令碼

8 開機啟動指令碼_在 Ubuntu 上使用 systemd 配置開機執行指令碼

技術標籤:8 開機啟動指令碼

簡述

在配置自用伺服器時,經常需要在開機後啟動某些服務。人工登入後手動啟動服務肯定可行,但本文希望節省人工干預的時間。省出來的時間可以用來陪家人、學習、鍛鍊身體,也可以用來發呆、睡覺,反正就不要花時間進行重複的機械性操作。

為此,本文使用 systemd 配置的方式讓 Ubuntu 系統在開機且未登入的的狀態下執行特定的 Shell 指令碼。

本文原為《基於加密的 RAID-1 硬碟陣列搭建 Nextcloud 私有網路硬碟服務》文章中闡述配置開機啟動 Nextcloud 服務的章節,因配置開機執行指令碼的方法具有通用的參考價值,故另起本文詳述。

systemd

systemd 可以看作是 Linux 系統下的服務管理者,已被應用到很多主流的 Linux 發行版中(如 Ubuntu, Debian, Fedora 等)用於系統管理。如在 Ubuntu 20.04 上用命令列關機,可直接使用如下 systemd 提供的命令:

sudo systemctl poweroff

本文選取 systemd 實現開機執行 Shell 指令碼有兩個原因:

  1. 配置方法簡便。
  2. systemd 已被 Linux 發行版廣泛採用,使用 systemd 在開機時執行指令碼可以認為是一種官方建議做法。

通用操作步驟

  • 建立希望開機馬上執行的指令碼,本文舉例指令碼存放位置為 /home/tqh/Documents/Example/StartupScipt.sh,指令碼內容如下:
#!/bin/sh
# 開機時在指令碼的同級目錄下建立一個名為 StartupTouch.txt 的檔案
touch /home/tqh/Documents/Example/StartupTouch.txt
  • 開機執行的指令碼需增加可執行許可權才能被 systemd 執行,使用如下命令
chmod u+x /home/tqh/Documents/Example/StartupScipt.sh
chmod g+x /home/tqh/Documents/Example/StartupScipt.sh
  • 進入 systemd 放置 service 的目錄,在該目錄下可看到大量服務配置檔案,命令如下
# 進入 systemd 的 service 目錄
cd /etc/systemd/system
# 檢視檔案列表
ls -al
  • 在該目錄建立一個新的 .service 檔案用於配置開機啟動指令碼,本例中的檔名為 StartupExample.service,所執行命令和檔案中的配置內容如下:
# 建立服務配置檔案
sudo touch /etc/systemd/system/StartupExample.service

# 以下為 StartupExample.service 配置檔案的內容
[Unit]
Description=Startup Example

[Service]
ExecStart=/home/tqh/Documents/Example/StartupScipt.sh

[Install]
WantedBy=multi-user.target
  • 嘗試手動執行新建立的 service,使用如下命令:
# 手動執行 StartupExample.service
sudo systemctl start StartupExample.service
# 檢視執行日誌
systemctl status StartupExample.service

c528bbf1db84bd956a03cd2ad0740b30.png
執行日誌顯示:服務啟動成功
  • 檢視服務中建立的檔案是否建立成功,使用如下命令:
ls -al /home/tqh/Documents/Example/

c96a9f561c25a4cca13fda6783b5823f.png
檔案建立成功,證明服務配置已生效
  • 刪除檔案後將服務設定為 enable 狀態,再重啟計算機,看服務是否能正常執行。使用如下命令:
# 刪除剛測試服務時建立的檔案
rm -f /home/tqh/Documents/Example/StartupTouch.txt
# 設定服務為 enable 狀態,使之能開機執行
sudo systemctl enable StartupExample.service
# 重啟機器
systemctl reboot
  • 下圖中能看到開機執行的指令碼中 touch 的檔案已經建立成功

04a5d44f7a07c1f8683078d0f02db1f1.png
檔案建立成功,證明開機執行的指令碼已配置完成

啟動 Nextcloud 服務的操作步驟

本章將對《基於加密的 RAID-1 硬碟陣列搭建 Nextcloud 私有網路硬碟服務》一文中配置開機啟動 Nextcloud 服務的部分進行細述,除用到上述通用的操作步驟外,還有特殊情況需要討論處理。

  • 建立啟動 Nextcloud 服務的指令碼併為之增加可執行許可權,操作如下
# 建立開機啟動 Nextcloud 的指令碼
touch /mnt/data/nextcloud/start_nextcloud.sh

# 為指令碼增加可執行許可權
chmod u+x /mnt/data/nextcloud/start_nextcloud.sh
chmod g+x /mnt/data/nextcloud/start_nextcloud.sh
  • 編輯指令碼內容如下
#!/bin/sh

docker run -d  
-p 8080:80 
-v /mnt/data/nextcloud/data:/var/www/html 
nextcloud
  • 在 /etc/systemd/system 目錄下新建服務描述檔案 Nextcloud.service,操作及檔案內容如下
# 建立 systemd 使用的 service 描述檔案
sudo touch /etc/systemd/system/Nextcloud.service

# 以下為 Nextcloud.service 的檔案內容
[Unit]
Description=Nextcloud Service

[Service]
ExecStart=/mnt/data/nextcloud/start_nextcloud.sh

[Install]
WantedBy=multi-user.target
  • 設定 Nextcloud.service 為開機啟動並重啟計算機,操作如下
# 設定 Nextcloud.service 為開機啟動
sudo systemctl enable Nextcloud.service
# 重啟機器
sudo systemctl reboot
  • 重啟後檢視執行日誌,所執行命令及其結果如下
# 檢視 systemd 的執行日誌
systemctl status Nextcloud.service

87ab0a13d58c9a787a7ebc8da95423c6.png
執行失敗:找不到指令碼檔案
根據日誌中的報錯資訊,發現開機後 systemd 要執行 Nextcloud.service 時找不到指令碼。結合該文中加密硬碟陣列分割槽的使用方法,可疑的原因是 啟動服務時指令碼所在的硬碟分割槽未掛載完成
解決的思路是等待分割槽掛載完成再執行啟動 Nextcloud 服務的指令碼。
  • 先找到掛載 /mnt/data 的服務,使用命令和執行結果如下
systemctl list-unit-files

413d15035474afa31380b642b89e8ab7.png
在 systemd 的 UNIT 列表中找到了 mnt-data.mount 的掛載操作
  • 使用文字工具修改 Nextcloud.service 檔案,增加語句 “ After=mnt-data.mount ”保證硬碟分割槽的掛載操作先執行,修改後的檔案如下
[Unit]
Description=Nextcloud Service
After=mnt-data.mount

[Service]
ExecStart=/mnt/data/nextcloud/start_nextcloud.sh

[Install]
WantedBy=multi-user.target
  • 重啟計算機後檢視 systemd 執行日誌,使用命令和執行結果如下
# 重啟機器
sudo systemctl reboot
# 檢視 systemd 的執行日誌
systemctl status Nextcloud.service

e2173ad3df8cd5b5681243934093f18a.png
Nextcloud.service 啟動成功

至此, 開機啟動 Nextcloud 服務的配置操作已經完成。

附語

有很多特殊原因可能導致使用通用的 systemd 配置開機啟動指令碼方法時失敗,建議使用 systemd 的 status 命令檢視日誌以定位問題。

systemctl status ***.service