Jak poprawnie skonfigurować zadanie root cron

36

Próbowałem skonfigurować zadanie root cron do uruchamiania skryptu Bash jako root, aby uruchamiał się z minutą 7,37, co godzinę, każdego dnia miesiąca, każdego miesiąca. Ten skrypt znajduje się w /usr/binnazwie i nazywa tunlrupdate.sh. Aktualizuje DNS Tunlr.

$ ls -l /usr/bin/tunlrupdate.sh 
-rwxr-xr-x 1 root root 2133 Sep 24 15:42 /usr/bin/tunlrupdate.sh

Ten skrypt Bash jest dostępny tutaj .

Po wywołaniu skrypt zapisuje, co dzieje się w logu znajdującym się w /var/log/tunlr.log

Aby dodać to zadanie root crona, użyłem standardu dla crontab roota

sudo crontab -e

I wstawiłem te 2 linie na końcu. Oczekuję, że cron uruchomi skrypt jako root.

# check for updated Tunlr DNS every 30 minutes at the hour + 7 mn and hour + 37 mn
07,37 * * * * root /usr/bin/tunlrupdate.sh

Późniejsze polecenie sudo crontab -lpotwierdziło, że zadanie cron zostało wstawione.

Zrestartowałem Ubuntu i sprawdzałem w pliku dziennika, czy zadanie cron zostało poprawnie uruchomione. Jednak w pliku dziennika nie ma nic, /var/log/tunlr.logco oznacza, że ​​zadanie nigdy nie zostało pomyślnie uruchomione.

Sprawdziłem, czy uruchamiam skrypt z wiersza poleceń

sudo /usr/bin/tunlrupdate.sh

następnie plik dziennika jest odpowiednio aktualizowany.

Dlaczego to zadanie cron nie działa zgodnie z planem w moim systemie?

AKTUALIZACJA 1: Wszystkie dotychczas zaproponowane rozwiązania nie działają. Dziękuję Olli za interfejs CLI do wyświetlenia dziennika systemu sudo grep CRON /var/log/syslog. Jednak dostałem błąd CRON

CRON[13092]: (root) CMD (  [ -x /usr/lib/php5/maxlifetime ] && [ -d /var/lib/php5 ]
&& find /var/lib/php5/ -depth -mindepth 1 -maxdepth 1 -type f -cmin +$(/usr/lib/php
/maxlifetime) ! -execdir fuser -s {} 2>/dev/null \; -delete)

z sugerowaną ŚCIEŻKĄ = wstawienie i użycie ścieżki bezwzględnej z katalogu głównego dla funkcji w skrypcie lub bez sugerowanych rozwiązań tutaj. Nadal pojawia się ten błąd.

Po kilku poszukiwaniach wskazałem błąd w pliku, /usr/lib/php5/maxlifetimejak wyjaśniono tutaj :Change #!/bin/sh -e --> #!/bin/sh -x

Następnie wyświetlam dziennik błędów CRON w moim systemie

sudo grep CRON /var/log/syslog
Feb 11 18:07:01 Marius-PC CRON[14067]: (root) CMD (root /usr/bin/tunlrupdate.sh)
Feb 11 18:07:01 Marius-PC CRON[14066]: (root) MAIL (mailed 1 byte of output; but got
status 0x00ff, #012)

Nadal nie uruchamiam skryptu bash. Tym razem w dzienniku nie ma błędu. Aby uzyskać pewność, że nie była to treść skryptu, zredukowałem skrypt do następujących 3 wierszy:

#!/bin/bash
LOGFILE=/var/log/tunlr.log
echo $LOGFILE >> $LOGFILE

Nadal nie dostaję pracy crona. W pliku dziennika nic nie jest zapisane. Więc może nawet pusty skrypt nie będzie działał w cronie? Nie rozumiem Wiem, że próbuję skryptu zredukowanego do tych 2 wierszy:

#!/bin/bash
exit 0

I wciąż ten sam dziennik błędów. Skrypt crona nie przechodzi ...

Antonio
źródło
Jeśli chcesz, aby robił to „root” cronjob, musisz być rootem, a następnie wpisz crontab -e. Musisz także zalogować się jako root (konsola typu „su root”), a następnie crontab -e (w tym przypadku sudo nie jest potrzebne).
Wolfgang
Dobrze. Nie rozumiem sensu twojej odpowiedzi? Wpisanie $ sudo crontab -e wykonało zadanie zgodnie z raportem $ sudo crontab -l, tj. Wiersz opisujący nowe zadanie został dodany do crona root. Jak per se, zadanie nie jest obecne w cronie użytkownika, np. $ Crontab -l nie pokazuj, że tutaj zostało dodane żadne zadanie crona.
Antonio
@WolfgangVogl użył „sudo”, który działa zgodnie z oczekiwaniami.
Alexis Wilke

Odpowiedzi:

68

Jeśli chcesz uruchomić skrypt jako zwykły użytkownik :

crontab -e

I dodaj wiersz:

07,37 * * * * /usr/bin/tunlrupdate.sh

Jeśli chcesz uruchomić skrypt jako root :

sudo crontab -e

I dodaj tę samą linię:

07,37 * * * * /usr/bin/tunlrupdate.sh
Guillaume
źródło
@NineCattoRules Jeśli nie upuścisz wyjścia, co widzisz?
Angelo Fuchs
@AngeloFuchs stary komentarz ... na pewno próbowałem tego polecenia jako root ( sudo crontab -ezamiast crontab -e). Lub coś innego, w każdym razie to działa
NineCattoRules
10

Wreszcie działające rozwiązanie. W syslogu widziałem powtarzające się i intrygujące:

CRON[18770]: (root) CMD (root /usr/bin/tunlrupdate.sh)

To brzmi jak root nie został rozpoznany jako cmd. Jak już użyłem crona root'a za pomocą $ sudo /usr/bin/tunlrupdate.sh. Następnie spróbowałem z oryginalnym skryptem (poprawionym pod kątem błędu w dacie UNIX cmd:% m, który jest miesiącem był używany przez minuty, co jest% M), następującą (która usuwa root z linii cron):

$ sudo crontab -e
# check for updated Tunlr DNS every 30 minutes at the hour + 7 mn and hour + 37 mn
07,37 * * * * /usr/bin/tunlrupdate.sh

To okazało się ostatecznym rozwiązaniem. [Chociaż znalazłem mnóstwo literatury stwierdzającej błędną linię z pierwiastkiem w linii crona. To był błąd].

Antonio
źródło
Dobra uwaga Olli. Zgadzam się w tym z tobą. Dla odniesienia crontab użytkownika jest przechowywany w / var / spool / cron / crontabs / user-name lub dla root / var / spool / cron / crontabs / root. Zobacz tę stronę askubuntu.com/questions/216692/where-is-the-user-crontab-stored Folder zawierający już znajduje się i podaje nazwę użytkownika.
Antonio
Cóż, nie powinieneś potrzebować tych informacji, ponieważ powinieneś edytować tylko pliki crontab z crontabpoleceniem (z wyjątkiem plików crontab pod /etc).
Olli
1
@Antonio wyniki z polem nazwy użytkownika są używane tylko w /etc/crontab(crontab dla całego systemu). Używając sudo crontab -epracujesz z /var/spool/cron/crontabs
crontabem
2

Jednym z „problemów” z cronem jest brak zmiennych środowiskowych (z oczywistych względów bezpieczeństwa). Prawdopodobnie brakuje ci PATH i HOME. Możesz zdefiniować je w skrypcie bezpośrednio lub w pliku crontab.

# check for updated Tunlr DNS every 30 minutes at the hour + 7 mn and hour + 37 mn
PATH=/usr/bin
07,37 * * * * root /usr/bin/tunlrupdate.sh

Będziesz musiał testować, aż wszystkie niezbędne zmienne zostaną zdefiniowane zgodnie z wymaganiami skryptu.

Alexis Wilke
źródło
1
To jedyna odpowiedź, która faktycznie dla mnie zadziałała. Skopiowałem instrukcje SHELL i PATH z /etc/crontabpliku i wkleiłem je do, sudo crontab -ea polecenie uruchomiło się jako root bez problemu. Dziękuję Ci!
Terrance
0

Komunikaty o błędach Cron są zazwyczaj - domyślnie - wysyłane pocztą e-mail. Możesz sprawdzić, czy jest e-mail do rootowania sudo mail, lub po prostu sprawdzając zawartość /var/mail/rootnp sudo less /var/mail/root.


Jeśli wiadomości e-mail nie pomagają, sprawdź również /var/log/syslog:

sudo grep CRON /var/log/syslog

Jak już powiedziała Alexis Wilke, cron ma inny mechanizm ustawiania zmiennych środowiskowych.

Twój skrypt potrzebuje

PATH=/sbin:/bin:/usr/bin

do crontab. HOMEnie powinno być konieczne. Powinieneś używać ścieżek bezwzględnych w swoich skryptach, np. /bin/dateZamiast date. Możesz znaleźć odpowiednie ścieżki dla każdego polecenia za pomocą which command_namenp

$ which date
/bin/date
Olli
źródło
Uruchamianie twojego sugerowanego grep CRON w / var / log / syslog Mam foolowing 11 lutego 14:37:01 Marius-PC CRON [7826]: (root) CMD (root /usr/bin/tunlrupdate.sh) 11 lutego 14: 37:01 Marius-PC CRON [7825]: (root) MAIL (wysłano 1 bajt wyjścia; ale otrzymał status 0x00ff, # 012) 11 lutego 14:39:01 Marius-PC CRON [7849]: (root) CMD ( [-x / usr / lib / php5 / maxlifetime] && [-d / var / lib / php5] i& find / var / lib / php5 / -depth -mindepth 1 -maxdepth 1 -typ f -cmin + $ (/ usr / lib / php5 / maxlifetime)! -execdir fuser -s {} 2> / dev / null \; -delete) Jeśli dodam jakąś definicję ŚCIEŻKI w cronie, nie wpłynie to na mój system $ PATH?
Antonio
Ten wynik mówi, że próbował wysłać coś pocztą e-mail, ale nie powiódł się. Oznacza to, że nie wyświetla się ten komunikat o błędzie /var/mail/root. Możesz to naprawić lub spróbowaćPATH=...
Olli
@Antonio lub skorzystaj z tej poprawionej wersji
Olli
Dzięki. Wiem, że nie skonfigurowałem systemowego adresu e-mail i wiedziałem, że nie udało mi się. Już zmodyfikowałem skrypt, aby używał ścieżki bezwzględnej dla dowolnej wywoływanej funkcji. Ostatnią rzeczą było moje poprzednie pytanie, czy definicja PATH w crontab nie zepsuje mojej systemowej zmiennej PATH?
Antonio
1
W międzyczasie byłem zajęty poprawianiem błędu w formacie daty z oryginalnego skryptu. Używał% m (co nie jest minutą miesiąca) zamiast% M ...
Antonio
0

Możesz dodać tę linię do skryptu. Więc po sprawdzeniu dzienników cron i sprawdzeniu, czy zadanie zostało wykonane, możesz dostać taką samą ścieżkę $ crontabs.

/bin/echo $PATH > /root/path.txt

Prawdopodobnie najlepszą rzeczą, jaką możesz zrobić, aby zdiagnozować problemy w skryptach cron, jest pobranie wszystkich zmiennych środowiskowych SO za pomocą komendy env w skrypcie. Więc po prostu dodaj tę linię do skryptu. Następnie możesz przeanalizować dane wyjścioweallEvnVars.txt

/usr/bin/env > /root/allEvnVars.txt

Inną sztuczką jest skierowanie wyjścia skryptu do jakiegoś miejsca. Dodawanie /root/log.log. W ten sposób wszystkie dane wyjściowe skryptu zostaną zachowane/root/log.log

07,37 * * * * root /usr/bin/tunlrupdate.sh  > /root/log.log

Ponadto można zaplanować uruchamianie skryptu co minutę, aby ułatwić testy i kontrole.

*/1 * * * * root /usr/bin/tunlrupdate.sh  > /root/log.log
Cassio Seffrin
źródło