systemd和終端啟動程序的區別
我很好奇這些程序之間的區別是什麼;通過 systemctl 啟用時使用 systemd 啟動,與通過 CLI 啟動
/etc/rc.local
或通過 CLI 啟動的相比。例如,我最近在樹莓派上使用了 shairport-sync。最初,我通過 sudo systemctl enabled shairport-sync 將 shairport-sync 設置為啟動。
後來,我使用其中的一個功能在
shairport-sync
之前執行腳本並將其發佈到連接的設備。令我驚訝的是,腳本在執行
shairport-sync
時沒有kill
arecord
或aplay
但是,當我通過終端執行腳本時,腳本會執行並終止,
arecord
並且aplay
.為了進一步混淆自己,我
shairport-sync
通過終端殺死並啟動它以查看正在發生的事情的輸出。當我這樣做時,腳本在設備連接並終止時按預期執行,arecord
並且aplay
. 因此,作為修復,我禁用shairport-sync
並將sysmtectl
其設置/etc/rc.local
為作為快速修復執行。之後reboot
它按我的預期執行。這使我相信,作為獨立執行的程序與通過CLI 或 CLI
systemd
啟動時執行的程序之間存在一些差異。/etc/rc.local
為什麼會這樣?這是因為執行級別不同嗎?有什麼黑魔法?
設備連接時執行的腳本
shairport-sync
如下:shairportstart.sh
#!/bin/sh /usr/bin/sudo /bin/pkill arecord if [ $(date +%H) -ge "18" -o $(date +%H) -le "7" ]; then /usr/bin/amixer set Speaker 40% else /usr/bin/amixer set Speaker 100% fi /home/pi/shScripts/shairportfade.sh& exit 0
這是淡化腳本:
shairportfade.sh
#!/bin/sh /usr/bin/amixer set Speaker 30- for (( i=0; i<30; i++)) do /usr/bin/amixer set Speaker 1+ done exit 0
設備斷開連接時執行的腳本
shairport-sync
如下:shairportend.sh
#!/bin/sh /usr/bin/amixer set Speaker 70% /usr/bin/arecord -D plughw:1 -f dat | /usr/bin/aplay -D plughw:1 -f dat& exit 0
僅當shairport
/var/log/syslog
-sync 最初作為systemd
. 何時shairport-sync
從 CLI 執行或/etc/rc.local
不存在錯誤。Jan 24 00:38:45 raspberrypi shairport-sync[617]: sudo: no tty present and no askpass program specified
請注意,唯一的區別是
shairport-sync
最初如何啟動,當設備連接或斷開連接時shairport-sync
繼續執行。
*“為什麼事情在 systemd 下表現不同?”*的變體 是一個經常被問到的問題。
任何時候從 CLI 而不是從 systemd 執行某些東西時,都有一些廣泛的可能性類別可以解釋差異。
- 不同的環境變數。在生成的程序中的環境變數部分
systemd
記錄它傳入的環境變數。如果您想自己檢查差異,可以使用,它將在瞬態範圍內執行您的應用程序,就像它由 systemd 服務執行一樣。你會得到如下輸出:. 然後您可以查看輸出。修改您的應用程序以轉儲它接收到的環境變數,並將 CLI 執行與 systemd 執行進行比較。如果不方便修改應用程序,您可以使用查看將傳遞的環境變數並查看生成的日誌記錄。如果您嘗試啟動 X11 GUI 應用程序,則需要設置環境變數man systemd.exec``systemd-run /path/to/binary``Running as unit: run-u160.service``journalctl -u run-u160.service``systemd-run env
DISPLAY
. 在這種情況下,請考慮使用桌面環境的“自動啟動”功能而不是systemd
.- 資源限制。有關
man systemd.resource-control
可能限制資源消耗的配置值,請參閱。用於systemctl show your-unit-unit.service
檢查影響您嘗試啟動的服務的完整配置值。- 非互動式外殼。您的
bash
CLI 環境是一個互動式登錄 shell。它有類似的源.bashrc
文件systemd
。除了設置環境變數,這些腳本還可以做很多其他事情,比如連接一個 SSH 代理,這樣 SSH 操作就不需要登錄。另請參閱登錄 Shell 和非登錄 Shell 之間的區別?- 沒有電傳打字機。您的互動式會話連接到某些程序在提示輸入密碼時喜歡
sudo
和期望的 TTY。ssh
另請參閱sudo:不存在 tty 且未指定 askpass 程序- 相對路徑與絕對路徑。shell 中的相對二進制工作,但如 中
man systemd.service
所述,第一個參數ExecStart=
必須是二進制的絕對路徑。- 受限制的命令行語法。Shell CLI 支持許多元字元,同時
systemd
具有非常有限的命令行語法。根據您的需要,您可以systemd
通過 shell 顯式執行命令來複製 Shell 語法:ExecStart=/bin/bash -c '/my/bash $(syntax) >/goes-here.txt'
這是系統在具有資源控制的一致環境中執行您的程式碼的一項功能。從長遠來看,這有助於在不壓倒硬體的情況下獲得可重複、穩定的結果。