之前開發遇到的一個問題:在Linux中,明明程序腳本可以手動執行成功,但加到開機自啟動里,卻會失敗,屬實讓人摸不著頭腦。
問題排查:
有以下幾種可能:
- 自啟動腳本,執行權限不足或者腳本中使用了相對路徑;
- 程序依賴其他服務,需要等待前置服務完全可用,比如依賴數據庫、消息隊列等;
- 開機啟動時未加載用戶自定義的環境變量(如PATH、LD_LIBRARY_PATH等)
解決辦法
前兩個很好解決,設置權限,修改腳本,增加sleep時間即可。
而博主剛好遇到是第三種情況,軟件需要配置自定義的環境變量,盡管在/etc/profile中已經設置了環境變量,但是當只把程序的開啟自啟動加在rc.local中時,程序所需要的環境變量并不會被自動加載進來。可以在rc.local中在xx.sh命令之前先export 自定義的環境變量,完美解決。
深入分析
追本溯源,先來看一下Linux系統中rc.local的啟動順序
第一步:init /etc/inittab
第二步:啟動相應的腳本,并且打開終端
rc.sysinit
rc.d(里面的腳本)
rc.local
第三步:啟動login登錄界面 login
第四步:在用戶登錄的時候執行sh腳本的順序,每次登錄的時候都會完全執行的
/etc/profile.d/file
/etc/profile
/etc/bashrc
/root/.bashrc
/root/.bash_profile
這說明rc.local運行在操作系統完全引導成功,但是尚未啟動login shell之前。比如我們可以在rc.local中加入env把環境變量打印出來,可以看到環境變量非常少。如果我們在/etc/profiles或bashrc中配置了環境變量,xx.sh依賴這些環境變量,由于rc.local執行階段看不到這些環境變量,所以會執行失敗。
該問題的解決辦法:在rc.local中在xx.sh命令之前加上export。