如何在網路故障時以 crontably 重啟 Linux 主機?
我有一個個人Ubuntu主機,連接到公共/共享 Wi-Fi AP(不受我控制)。
有時,它會出現網路問題,我很確定,僅重新啟動網路服務是行不通的。唯一的方法是重新啟動它。
我的計劃是添加一個 crontab 來測試網路連接。如果失敗,則重新啟動電腦。
如果我手動執行 auto_reboot.sh,它會在*ping*測試失敗時重新啟動。但是從 crontab 執行,它不起作用:)
這是我的 crontab 條目
crontab -l * * * * * /root/loadrc/transmissionrc/auto_reboot.sh
文件*/root/loadrc/transmissionrc/auto_reboot.sh*
#!/bin/zsh /root/loadrc/networkrc/ping.sh rc=$? if [[ $rc -eq 0 ]] then echo "say The internet is back up." else reboot fi
文件*/root/loadrc/networkrc/ping.sh*
#!/bin/zsh ((count = 10)) # Maximum number to try. while [[ $count -ne 0 ]] ; do ping -c 1 8.8.8.8 # Try once. rc=$? if [[ $rc -eq 0 ]] ; then ((count = 1)) # If okay, flag loop exit. else sleep 1 # Minimise network storm. fi ((count = count - 1)) # So we don't go forever. done exit $rc
我添加了一些日誌,並且故意拉低了 Wi-Fi 介面:
watch ifconfig wlan0 down
transmissionrc/auto_reboot.sh #!/bin/zsh echo "" > /root/loadrc/crontab.log /root/loadrc/networkrc/ping.sh rc=$? if [[ $rc -eq 0 ]] then echo "say The internet is back up." else reboot fi
networkrc/ping.sh #!/bin/zsh ((count = 10)) # Maximum number to try. while [[ $count -ne 0 ]] ; do /usr/bin/ping -c 1 8.8.8.8 >> /root/loadrc/crontab.log 2>&1 echo "step --> 2" >> /root/loadrc/crontab.log rc=$? if [[ $rc -eq 0 ]] ; then echo "step --> 3" >> /root/loadrc/crontab.log ((count = 1)) # If okay, flag loop exit. else echo "step --> 4" >> /root/loadrc/crontab.log sleep 1 # Minimise network storm. fi ((count = count - 1)) # So we don't go forever. done exit $rc
文件*/root/loadrc/crontab.log*
/usr/bin/ping: connect: Network is unreachable step --> 2 step --> 3
這意味著,在 crontab 模式下,即使 ping 測試失敗,返回碼仍然為零。
那麼問題來了:如何在crontab模式下測試網路連接?
對於您的問題的可能解決方案,我有三個想法:
1. 你說:
If I manually run the auto_reboot.sh, it does reboot, when a ping test fail. But running from crontab, it is not working:)
通常,當一個命令在您的互動式 shell(來自 CLI)中正常執行,但
cron
由於環境不同而無法在其下正常執行時;例如cron
,與您在互動式 shell 中所做的 PATH 不同。通常,cron
環境是:PATH=/usr/bin:/bin
。您執行的任何腳本cron
都無法找到不在 PATH 上的執行檔。順便說一句,您
cron
只需env
使用以下命令執行即可檢查系統上的環境crontab
:* * * * * /usr/bin/env > /my/cronlog/location/mycronenvironment.txt 2>&1
在您的中
auto_reboot.sh
,您未能為. 正如通常在 中找到的那樣,並且可能不在 使用的 PATH 中,這是一個潛在的問題。reboot``reboot``/sbin/reboot``/sbin
cron
因此,我建議您驗證 使用的環境 (PATH)
cron
,並仔細檢查您的所有命令是:1) 在cron
PATH 上,或 2) 使用完整路徑規範。2. 你把所有東西都跑出
/root
目錄通常,
/root
不用於使用者腳本。也許你正在使用sudo
?或者,也許你已經做了一個su
成為根?如果是這種情況,我會評論說這不是最佳實踐,即使它仍然可以工作。我覺得最好的做法是sudo
從您的使用者帳戶中使用您需要的任何權限提升。不想學究氣,我想說該
root
帳戶有一個crontab
獨立於任何使用者crontab
執行的帳戶。此外,root crontab
不需要sudo
使用 - 在 中完成的所有操作root crontab
都是通過root
特權完成的。綜上所述,我
reboot
在您的腳本中看到了對的呼叫 - 一個需要root 權限才能執行的命令。只有在root crontab
. _ 您的問題並未表明您是否正在使用su
orsudo
,因此我通過這個來努力澄清兩點:
- 如果您的
cron
作業需要root
特權,最好從root crontab
. 另一種方法是sudo
在user crontab
需要身份驗證的情況下使用可能會很尷尬sudo
- 通常情況下。
root crontab
可以從普通使用者帳戶訪問,只需使用sudo crontab -e
; 即不需要su
訪問.root``root crontab
3.你的腳本可能有邏輯錯誤
正如另一個答案中所指出的,
rc
您是否可以依賴ping.sh
腳本中的值作為reboot
. 不幸的是,這是否是一個問題被ping.sh
您問題中腳本的兩個不同版本所掩蓋 - 目前尚不清楚您是否使用第一個版本:#!/bin/zsh ((count = 10)) # Maximum number to try. while [[ $count -ne 0 ]] ; do ping -c 1 8.8.8.8 # Try once. rc=$?
或第二個版本:
#!/bin/zsh ((count = 10)) # Maximum number to try. while [[ $count -ne 0 ]] ; do /usr/bin/ping -c 1 8.8.8.8 >> /root/loadrc/crontab.log 2>&1 echo "step --> 2" >> /root/loadrc/crontab.log rc=$?
嚴格來說,作為我個人的選擇,我傾向於將這兩個腳本 (
ping.sh
和auto_reboot.sh
) 中的程式碼合併到一個腳本中,因為這對我來說似乎更簡單,但你可能有充分的理由這樣做,而且沒有理由這樣做’如果操作正確,將無法正常工作。