Puncte:2

Cum pot reporni crontabil o gazdă Linux la o defecțiune a rețelei?

drapel id

Am un personal Ubuntu gazdă, conectată la o rețea Wi-Fi publică/de partajare AP (nu sub controlul meu).

Uneori, ar avea o problemă de rețea și sunt foarte sigur că doar repornirea serviciului de rețea nu ar funcționa. Singura modalitate este să-l reporniți.

Planul meu este să adaug un crontab, pentru a testa conexiunea la rețea. Dacă eșuează, reporniți computerul.

Dacă rulez manual auto_reboot.sh, acesta se repornește, când a ping test esuat. Dar rulând din crontab, nu funcționează:)

Aici este intrarea mea crontab

crontab -l
* * * * * /root/loadrc/transmissionrc/auto_reboot.sh

Fişier /root/loadrc/transmissionrc/auto_reboot.sh

#!/bin/zsh

/root/loadrc/networkrc/ping.sh
rc=$?

dacă [[ $rc -eq 0 ]]
atunci
    echo "spune că Internetul este înapoi."
altfel
    reporniți
fi

Fişier /root/loadrc/networkrc/ping.sh

#!/bin/zsh
((număr = 10)) # Număr maxim de încercat.

în timp ce [[ $count -ne 0 ]] ; do
    ping -c 1 8.8.8.8 # Încercați o dată.
    rc=$?
    dacă [[ $rc -eq 0 ]] ; atunci
        ((număr = 1)) # Dacă este bine, semnalați ieșirea buclei.
    altfel
        sleep 1 # Minimizați furtuna de rețea.
    fi
    ((număr = număr - 1)) # Deci nu mergem pentru totdeauna.
Terminat

ieșiți din $rc

Adaug niște jurnale și dobândesc în mod deliberat interfața Wi-Fi:

urmăriți ifconfig wlan0 jos
transmissionrc/auto_reboot.sh
#!/bin/zsh

echo "" > /root/loadrc/crontab.log

/root/loadrc/networkrc/ping.sh
rc=$?

dacă [[ $rc -eq 0 ]]
atunci
    echo "spune că Internetul este înapoi."
altfel
    reporniți
fi
networkrc/ping.sh
#!/bin/zsh
((număr = 10)) # Număr maxim de încercat.


în timp ce [[ $count -ne 0 ]] ; do
    /usr/bin/ping -c 1 8.8.8.8 >> /root/loadrc/crontab.log 2>&1
    echo "pasul --> 2" >> /root/loadrc/crontab.log
    rc=$?

    dacă [[ $rc -eq 0 ]] ; atunci
        echo "pasul --> 3" >> /root/loadrc/crontab.log
        ((număr = 1)) # Dacă este bine, semnalați ieșirea buclei.
    altfel
        echo "pasul --> 4" >> /root/loadrc/crontab.log
        sleep 1 # Minimizați furtuna de rețea.
    fi
    ((număr = număr - 1)) # Deci nu mergem pentru totdeauna.
Terminat

ieșiți din $rc

Fişier /root/loadrc/crontab.log

/usr/bin/ping: connect: Rețeaua este inaccesibilă
pasul --> 2
pasul --> 3

ceea ce înseamnă că, în modul crontab, chiar și testul ping eșuează, codul de returnare este încă zero.

Deci întrebarea vine la: cum pot testa conexiunea la rețea în modul crontab?

djdomi avatar
drapel za
pare o problemă x și y, care este problema inițială pe care încercați să o rezolvați?
drapel sn
Re *„o gazdă Ubuntu personală”*: Asta nu ar fi în afara subiectului?
drapel br
Nu aș folosi `cron` pentru asta, ci `watchdog`, care este special conceput pentru a reporni mașina locală dacă o anumită condiție eșuează și permite rularea comenzilor personalizate ca verificări.
Puncte:7
drapel cn
Bob
/usr/bin/ping -c 1 8.8.8.8 >> /root/loadrc/crontab.log 2>&1 
echo "pasul --> 2" >> /root/loadrc/crontab.log  
rc=$?

Cred că acest lucru verifică codul de ieșire al ecou comanda în timp ce logica dvs. are nevoie de codul de ieșire al ping comanda.

huangyingw avatar
drapel id
da, eroare în ecoul meu, mulțumesc că ai subliniat asta.
marcelm avatar
drapel ng
@huangyingw Deci, puteți actualiza întrebarea pentru a corecta asta?
Puncte:2
drapel il

Am trei gânduri despre soluțiile posibile la problema ta:

1. Ai spus:

Dacă rulez manual auto_reboot.sh, acesta se repornește atunci când un test ping eșuează. Dar rulând din crontab, nu funcționează:)

De obicei, atunci când o comandă rulează corect în shell-ul tău interactiv (din CLI), dar nu rulează corect sub cron se datorează unei diferențe în mediu inconjurator; de exemplu. cron are o cale diferită de cea a dvs. din shell-ul dvs. interactiv. De obicei, cel cron mediul este: PATH=/usr/bin:/bin. Orice scenariu alergi fugi sub cron nu va putea găsi executabile care nu sunt pe PATH.

Deoparte, puteți verifica cron mediu pe sistemul dvs. pur și simplu rulând înv folosind dvs crontab:

* * * * * /usr/bin/env > /my/cronlog/location/mycronenvironment.txt 2>&1

În dumneavoastră auto_reboot.sh, nu ați reușit să utilizați a specificații complete ale traseului pentru reporniți. La fel de reporniți se găsește de obicei în /sbin/reboot, și /sbin S-ar putea să nu fie în PATH folosit de cron, aceasta este o problemă potențială.

prin urmare, vă sugerez să verificați mediul (PATH) utilizat de cron, și verificați de două ori că toate comenzile dvs. sunt fie: 1) pe cron PATH, sau 2) utilizați a specificația completă a căii.

2. Epuizezi totul din /rădăcină director

De obicei, /rădăcină nu este folosit pentru utilizator scenarii. Poate că folosești sudo? Sau, poate ai făcut un su a deveni root? Dacă acesta este cazul, aș face-o cometariu că asta nu este cea mai buna practica, chiar dacă încă poate funcționa. simt cea mai buna practica este de a folosi sudo de la tine utilizator cont pentru orice escaladare a privilegiilor de care aveți nevoie.

Fără să încerc să fiu pedant, aș vrea să spun că rădăcină contul are un crontab care rulează independent de oricare utilizator crontab. De asemenea rădăcină crontab nu necesita sudo fi folosit - tot ce se face în rădăcină crontab se termina cu rădăcină privilegii.

Toate acestea spuse, văd apelul la reporniți în scriptul tău - o comandă care cere privilegii root pentru a rula. Aceasta va funcționa așa cum ați scris-o numai atunci când este utilizat în rădăcină crontab. Întrebarea dvs. nu a indicat dacă utilizați sau nu su sau sudo, și așa am trecut prin asta într-un efort de a clarifica două puncte:

  1. Dacă ale tale cron jobul cere rădăcină privilegii, ea pot fi cel mai bine să rulezi acel job de la rădăcină crontab. Alternativa este utilizarea sudo într-o utilizatorul crontab ceea ce este potențial incomod dacă este necesară autentificarea pentru sudo - așa cum se întâmplă adesea.
  1. The rădăcină crontab poate fi accesat dintr-un cont de utilizator obișnuit prin simpla utilizare sudo crontab -e; adică nu este obligat să o facă su la rădăcină pentru a accesa rădăcină crontab.

3. Este posibil să aveți o eroare logică în scriptul dvs

După cum se subliniază în alt raspuns, nu este clar că te poți baza pe valoarea de rc de la tine ping.sh scenariul ca o condiție pentru reporniți. Din păcate, dacă aceasta este sau nu o problemă este mascată de ceea ce par a fi două versiuni diferite ale ping.sh scriptul din întrebarea dvs. - nu este clar dacă utilizați prima versiune:

#!/bin/zsh
((număr = 10)) # Număr maxim de încercat.

în timp ce [[ $count -ne 0 ]] ; do
    ping -c 1 8.8.8.8 # Încercați o dată.
    rc=$?

sau a doua versiune:

#!/bin/zsh
((număr = 10)) # Număr maxim de încercat.


în timp ce [[ $count -ne 0 ]] ; do
    /usr/bin/ping -c 1 8.8.8.8 >> /root/loadrc/crontab.log 2>&1
    echo "pasul --> 2" >> /root/loadrc/crontab.log
    rc=$?

Strict ca alegere personală, aș prefera combinarea codului din aceste două scripturi (ping.sh și auto_reboot.sh) într-un singur script, deoarece mi se pare mai simplu, dar este posibil să aveți motive întemeiate să o faceți în acest fel și nu există niciun motiv că nu va funcționa dacă este făcută corect.

huangyingw avatar
drapel id
Mulțumesc pentru răspuns, da, am găsit motivul, trebuie să folosesc calea completă a comenzii de repornire. Am izolat logica într-un ping.sh, este pentru o mai bună reutilizare, poate că alte scripturi mele ar putea avea nevoie de ea. este Linux-ul meu personal fără cap doar pentru distracție, așa că m-am autentificat întotdeauna ca root, cron și scripturile sunt toate rulate ca root. o întrebare ulterioară: dacă eu (rădăcină) nu m-am conectat, își va face treaba cron-ul rădăcină? ceea ce vreau este un cron, chiar și niciun utilizator (inclusiv root) nu este conectat, ar rula în mod regulat și va verifica starea rețelei și va reporni dacă este necesar. @seamus
Seamus avatar
drapel il
@huangyingw: *"`o întrebare ulterioară: dacă eu (rădăcină) nu m-am autentificat, cron-ul rădăcină își va face treaba? `"* Da - `cron` este un *daemon* care rulează în fundal fără intervenția utilizatorului necesar; singurul său scop este de a rula joburi chiar și atunci când utilizatorul nu este autentificat.
huangyingw avatar
drapel id
mă bucur să aud, mulțumesc. @seamus
Seamus avatar
drapel il
@huangyingw: Cu plăcere - și vă rugăm să nu uitați să [votați orice răspuns pe care îl considerați *util* și *selectați* un răspuns](https://serverfault.com/help/someone-answers) dacă este cazul .

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.