使用 shell 檢測初始化系統
這可能與檢測作業系統有更多關係,但我特別需要係統上目前正在使用的init系統。
Fedora 15 和 Ubuntu 現在使用 systemd,Ubuntu 過去使用 Upstart(長期預設直到 15.04),而其他使用 System V 的變體。
我有一個我正在編寫的應用程序作為跨平台守護程序。初始化腳本是根據可在配置時傳入的參數動態生成的。
我想做的只是為他們正在使用的特定初始化系統生成腳本。這樣,安裝腳本可以在沒有參數的情況下以 root 身份合理執行,並且可以自動“安裝”守護程序。
這就是我想出的:
- 在 /bin 中搜尋 systemd、upstart 等
- 將 /proc/1/comm 與 systemd、upstart 等進行比較
- 詢問使用者
這樣做的最佳跨平台方式是什麼?
有點相關,*我可以依賴 bash 在大多數 nix 上還是依賴於發行版/作業系統?
目標平台:
- 蘋果系統
- Linux(所有發行版)
- BSD(所有版本)
- Solaris、Minix 和其他 *nix
對於第二個問題,答案是否定的,您應該查看可移植 shell 程式的參考資料。
至於第一部分——首先,你當然要小心。我會說執行幾個測試以確保- 因為有人確實安裝了systemd (例如)這一事實並不意味著它實際上被用作預設值
init
。此外,查看/proc/1/comm
可能會產生誤導,因為各種 init 程序的某些安裝可以自動/sbin/init
生成符號連結硬連結,甚至是主程序的重命名版本。也許最有用的事情可能是查看 init 腳本類型 - 因為這些是您實際創建的內容,無論執行它們的是什麼。
附帶說明一下,您還可以看看OpenRC,它旨在提供一種與 Linux 和 BSD 系統兼容的 init 腳本結構。
我自己也遇到了這個問題,並決定做一些測試。我完全同意應該為每個發行版單獨打包的答案,但有時會有實際問題阻止這種情況(尤其是人力)。
因此,對於那些想要“自動檢測”的人來說,這是我在一組有限的發行版中發現的(更多內容見下文):
- 你可以告訴暴發戶:
[[ `/sbin/init --version` =~ upstart ]] && echo yes || echo no
- 您可以通過以下方式告訴 systemd:
[[ `systemctl` =~ -\.mount ]] && echo yes || echo no
- 你可以告訴 sys-v init:
[[ -f /etc/init.d/cron && ! -h /etc/init.d/cron ]] && echo yes
這是我對以下命令行的實驗:
if [[ `/sbin/init --version` =~ upstart ]]; then echo using upstart; elif [[ `systemctl` =~ -\.mount ]]; then echo using systemd; elif [[ -f /etc/init.d/cron && ! -h /etc/init.d/cron ]]; then echo using sysv-init; else echo cannot tell; fi
在 ec2 實例上(我包括 us-east AMI id):
- ArchLinux:使用 systemd(自2012.10.06起)
- CentOS6.4 ami-52009e3b:使用暴發戶
- CentOS7 ami-96a818fe:使用 systemd
- Debian 6 ami-80e915e9:使用 sysv-init
- Debian 7.5 ami-2c886c44:使用 sysv-init
- Debian 7.6 GCE 容器虛擬機:使用 sysv-init
- RHEL 6.5 ami-8d756fe4:使用暴發戶
- SLES 11 ami-e8084981:使用 sysv-init
- Ubuntu 10.04 ami-6b350a02:使用暴發戶
- Ubuntu 12.04 ami-b08b6cd8:使用暴發戶
- Ubuntu 14.04 ami-a427efcc:使用新貴
- Ubuntu 14.10 及更低版本:使用 systemd
- AWS linux 2014.3.2 ami-7c807d14:使用暴發戶
- Fedora 19 ami-f525389c:使用 systemd
- Fedora 20 ami-21362b48:使用 systemd
只是要明確一點:我並不是說這是萬無一失的!,幾乎可以肯定不是。另請注意,為方便起見,我使用 bash 正則表達式匹配,但並非在任何地方都可用。以上對我來說已經足夠好了。但是,如果您發現發行版出現故障,請告訴我,如果有重現問題的 EC2 AMI,我會嘗試修復它…