Często crontab
skrypty nie są wykonywane zgodnie z harmonogramem lub zgodnie z oczekiwaniami. Istnieje wiele przyczyn:
- zła notacja crontab
- problem z uprawnieniami
- Zmienne środowiska
Ta wiki społeczności ma na celu zebranie najważniejszych powodów, dla których crontab
skrypty nie są wykonywane zgodnie z oczekiwaniami. Napisz każdy powód w osobnej odpowiedzi.
Podaj jeden powód na odpowiedź - szczegółowe informacje o tym, dlaczego nie został wykonany - i popraw (y) z tego jednego powodu.
Napisz tylko problemy specyficzne dla crona, np. Polecenia, które wykonują się zgodnie z oczekiwaniami ze strony powłoki, ale są wykonywane błędnie przez crona.
crontab -e
aby cron zaczął działać. Na przykład za pomocą vima edytuję plik i używam go:w
do napisania, ale zadanie nie jest dodawane do crona, dopóki też nie wyjdę. Więc nie zobaczę pracy, dopóki ja:q
też nie.Odpowiedzi:
Inne środowisko
Cron przekazuje minimalny zestaw zmiennych środowiskowych do twoich zadań. Aby zobaczyć różnicę, dodaj pracę zastępczą w ten sposób:
Poczekaj na
/tmp/env.output
utworzenie, a następnie ponownie usuń zadanie. Teraz porównaj zawartość/tmp/env.output
z danymi wyjściowymi poleceniaenv
run w swoim zwykłym terminalu.Częstym tutaj „gotcha” jest
PATH
inna zmienna środowiskowa. Może skrypt cron używa poleceniasomecommand
znalezione w/opt/someApp/bin
, który dodanych doPATH
w/etc/environment
? cron ignorujePATH
ten plik, więcsomecommand
uruchamianie ze skryptu nie powiedzie się, gdy zostanie uruchomione z cronem, ale zadziała po uruchomieniu w terminalu. Warto zauważyć, że zmienne z/etc/environment
będą przekazywane do zadań cron, tylko nie zmienne, które cron konkretnie ustawia, takie jakPATH
.Aby obejść ten problem, po prostu ustaw własną
PATH
zmienną u góry skryptu. Na przykładNiektórzy wolą zamiast tego używać ścieżek bezwzględnych do wszystkich poleceń. Odradzam to. Zastanów się, co się stanie, jeśli chcesz uruchomić skrypt w innym systemie, aw tym systemie jest
/opt/someAppv2.2/bin
zamiast tego polecenie. Musiałbyś przejść przez cały skrypt zastępując/opt/someApp/bin
go/opt/someAppv2.2/bin
zamiast po prostu niewielkiej edycji w pierwszym wierszu skryptu.Możesz także ustawić zmienną PATH w pliku crontab, który będzie obowiązywał dla wszystkich zadań cron. Na przykład
źródło
env
, zupełnie zapomniałem o tym poleceniu i myślałem, że ŚCIEŻKA działa. W moim przypadku było to zupełnie inne.Moja górna sprawa: jeśli zapomnisz dodać nowy wiersz na końcu
crontab
pliku. Innymi słowy, plik crontab powinien kończyć się pustą linią.Poniżej znajduje się odpowiednia sekcja na stronach podręcznika dla tego problemu (
man crontab
następnie przejdź do końca):źródło
man crontab
na Ubuntu 10.10 mówi: „cron wymaga, aby każdy wpis w crontab kończył się znakiem nowej linii. Jeśli ostatni wpis w crontab nie zawiera nowej linii, cron uzna crontab (przynajmniej częściowo) za zepsuty i odmawiaj instalacji ”. (A data na koniec to 19 kwietnia 2010 r.)crontab -e
, sprawdzi on składnię pliku przed zezwoleniem na zapis, w tym sprawdzenie znaku nowej linii.-e
opcji i jest niezależne od edytora.Demon Cron nie działa. Naprawdę spieprzyłem to kilka miesięcy temu.
Rodzaj:
Jeśli nie widzisz numeru, cron nie działa.
sudo /etc/init.d/cron start
może być użyty do uruchomienia crona.EDYCJA: Zamiast wywoływać skrypty inicjujące przez /etc/init.d, użyj narzędzia serwisowego, np
EDYCJA: Możesz także użyć systemctl we współczesnym Linuksie, np
źródło
pidof cron
który pominie wyniki dla innych aplikacji, które również mają słowo „cron”, np. Crontab.sudo service cron start
, dostanęstart: Job is already running: cron
service crond start
jeśli jego centos / RHELSkrypt pliki w
cron.d/
,cron.daily/
,cron.hourly/
, itd., Nie powinny zawierać kropki (.
), w przeciwnym razie run-parts je pominąć.Zobacz części robocze (8):
Tak więc, jeśli masz skrypt cron
backup.sh
,analyze-logs.pl
wcron.daily/
katalogu najlepiej usunąć nazwy rozszerzeń.źródło
run-parts --test
(lub inna wymyślona opcja, jak np--debug
.W wielu środowiskach cron wykonuje polecenia za pomocą
sh
, podczas gdy wiele osób zakłada, że będzie używaćbash
.Sugestie, aby przetestować lub naprawić to w przypadku niepowodzenia polecenia:
Spróbuj uruchomić polecenie,
sh
aby zobaczyć, czy to działa:Zawiń polecenie w podpowłokę bash, aby upewnić się, że zostanie uruchomione w bash:
Powiedz cronowi, aby uruchamiał wszystkie polecenia w bash, ustawiając powłokę u góry twojej crontab:
Jeśli polecenie jest skryptem, upewnij się, że skrypt zawiera shebang:
źródło
bash
, ale nie z niącron
. Dzięki!source
jest w bash, ale nie sh. W cron / sh użyj kropki:. envfile
zamiastsource envfile
.sh "mycommand"
mówi,sh
aby uruchomić mycommand jako plik skryptu. Miałeś na myślish -c "mycommand"
? W każdym razie wydaje się, że ta odpowiedź polega na tym, aby polecenie było uruchamiane w trybie bash, więc dlaczego dodałeśsh
tutaj polecenie ?Miałem pewne problemy ze strefami czasowymi. Cron działał ze świeżą strefą czasową instalacji. Rozwiązaniem było zrestartowanie crona:
źródło
* * * * * touch /tmp/cronworks
jak nic nie zrobiłem, ale jestRELOAD
na cronlog.W skryptach należy zastosować ścieżkę bezwzględną:
Na przykład
/bin/grep
należy użyć zamiastgrep
:Zamiast:
Jest to szczególnie trudne, ponieważ to samo polecenie będzie działać po uruchomieniu z powłoki. Powodem jest to, że
cron
nie ma tej samejPATH
zmiennej środowiskowej co użytkownik.źródło
/usr/bin/whatever
ścieżkiJeśli polecenie crontab zawiera
%
symbol, cron próbuje go zinterpretować. Więc jeśli korzystasz z dowolnego polecenia z nim%
zawartego (takiego jak specyfikacja formatu dla polecenia date), musisz go uciec.To i inne dobre gotcha tutaj:
http://www.pantz.org/software/cron/croninfo.html
źródło
date
wewnątrz zakładki cron?Cron wywołuje skrypt, który nie jest wykonywalny.
Po uruchomieniu
chmod +x /path/to/scrip
skrypt staje się wykonywalny i powinien rozwiązać ten problem.źródło
cron
i łatwe do zidentyfikowania, po prostu próbując wykonać/path/to/script
z wiersza poleceń.. scriptname
lubsh scriptname
lubbash scriptname
, wtedy staje się tocron
problemem specyficznym.Możliwe jest również, że hasło użytkownika wygasło. Nawet hasło roota może wygasnąć. Możesz,
tail -f /var/log/cron.log
a zobaczysz, że cron się nie powiedzie, a hasło wygasło. Możesz ustawić hasło, aby nigdy nie wygasało, wykonując następujące czynności:passwd -x -1 <username>
W niektórych systemach (Debian, Ubuntu) logowanie do crona nie jest domyślnie włączone. W /etc/rsyslog.conf lub /etc/rsyslog.d/50-default.conf wiersz:
należy edytować (
sudo nano /etc/rsyslog.conf
) bez komentarza w:Następnie musisz zrestartować rsyslog przez
lub
Źródło: Włącz rejestrowanie crontab w Debianie Linux
W niektórych systemach (Ubuntu) osobny plik rejestrowania dla crona nie jest domyślnie włączony, ale dzienniki związane z cronem pojawiają się w pliku syslog. Można użyć
aby wyświetlić wiadomości związane z cronem.
źródło
Jeśli twój kronikarze wywołuje aplikacje GUI, musisz powiedzieć im, jakiego WYŚWIETLACZA powinni użyć.
Przykład: uruchomienie Firefoksa z cronem.
Twój skrypt powinien
export DISPLAY=:0
gdzieś zawierać .źródło
* * * * * export DISPLAY=:0 && <command>
Problemy z uprawnieniami są dość powszechne, obawiam się.
Zauważ, że powszechnym obejściem jest wykonywanie wszystkiego przy użyciu crontab roota, co czasami jest naprawdę złym pomysłem. Ustawienie odpowiednich uprawnień jest zdecydowanie pomijanym problemem.
źródło
Niepewne uprawnienia do tabeli cron
Tabela cron jest odrzucana, jeśli jej uprawnienia są niepewne
Problem został rozwiązany
źródło
Skrypt jest wrażliwy na lokalizację. Jest to związane z zawsze stosowaniem bezwzględnych ścieżek w skrypcie, ale nie do końca tak samo. Twoje zadanie cron może wymagać
cd
przejścia do określonego katalogu przed uruchomieniem, np. Zadanie prowizji w aplikacji Rails może być konieczne w katalogu głównym aplikacji, aby Rake mógł znaleźć właściwe zadanie, nie wspominając o odpowiedniej konfiguracji bazy danych itp.Więc wpis w crontabie
23 3 * * * /usr/bin/rake db:session_purge RAILS_ENV=production
byłoby lepiej jak
Lub, aby zachować prostsze i mniej kruche zapisywanie pliku crontab:
23 3 * * * /home/<user>/scripts/session-purge.sh
z następującym kodem w
/home/<user>/scripts/session-purge.sh
:źródło
chdir(dirname(__FILE__));
Specyfikacje Crontab, które działały w przeszłości, mogą ulec uszkodzeniu podczas przenoszenia z jednego pliku crontab do drugiego. Czasami powodem jest przeniesienie specyfikacji z systemowego pliku crontab do pliku crontab użytkownika lub odwrotnie.
Format specyfikacji zadania cron różni się między plikami crontab użytkowników (/ var / spool / cron / nazwa użytkownika lub / var / spool / cron / crontabs / nazwa użytkownika) i crontabs systemu (
/etc/crontab
i pliki w/etc/cron.d
).Crontabs systemowe mają dodatkowe pole „użytkownik” bezpośrednio przed uruchomieniem komendy.
Spowoduje to błędy stwierdzające np.
george; command not found
Przeniesienie polecenia z/etc/crontab
lub pliku/etc/cron.d
do pliku crontab użytkownika.I odwrotnie, cron będzie dostarczał błędy podobne
/usr/bin/restartxyz is not a valid username
lub podobne, gdy nastąpi odwrotność.źródło
skrypt cron wywołuje polecenie z opcją --verbose
Miałem awarię skryptu cron, ponieważ byłem w trybie autopilota podczas pisania skryptu i zawarłem opcję --verbose:
Skrypt działał poprawnie podczas wykonywania z powłoki, ale nie powiódł się podczas uruchamiania z crontab, ponieważ pełne dane wyjściowe przechodzą do standardowego wyjścia przy uruchamianiu z powłoki, ale nigdzie przy uruchamianiu z crontab. Łatwa naprawa, aby usunąć „v”:
źródło
Najczęstszy powód, dla którego widziałem niepowodzenie crona w niepoprawnie określonym harmonogramie. Praktyka wymaga określenia zadania zaplanowanego na 23:15
15 23 * * *
zamiast* * 11 15 *
lub11 15 * * *
. Dzień tygodnia dla prac po północy też się myli MF jest2-6
po północy, nie1-5
. Określone daty są zwykle problemem, ponieważ rzadko ich używamy, nie* * 3 1 *
jest 3 marca. Jeśli nie jesteś pewien, sprawdź harmonogramy cron online pod adresem https://crontab.guru/ .Jeśli praca z różnymi platformami przy użyciu nieobsługiwanych opcji, takich jak
2/3
specyfikacje czasowe, może również powodować awarie. Jest to bardzo przydatna opcja, ale nie jest powszechnie dostępna. Mam również problemy z listami takimi jak1-5
lub1,3,5
.Korzystanie z niekwalifikowanych ścieżek również spowodowało problemy. Domyślna ścieżka to zwykle,
/bin:/usr/bin
więc uruchamiane będą tylko standardowe polecenia. Te katalogi zwykle nie mają żądanego polecenia. Wpływa to również na skrypty używające niestandardowych poleceń. Mogą również brakować innych zmiennych środowiskowych.Całkowite przeszukanie istniejącego crontabu sprawiło mi problemy. Teraz ładuję z kopii pliku. Można to odzyskać z istniejącego pliku crontab za pomocą
crontab -l
jeśli zostanie zablokowany. Trzymam kopię crontab w ~ / bin. Jest komentowany i kończy się linią# EOF
. To jest przeładowywane codziennie z pozycji crontab, takiej jak:Powyższe polecenie przeładowania opiera się na wykonywalnym pliku crontab z ścieżką hukową uruchomioną w pliku crontab. Niektóre systemy wymagają uruchomienia polecenia crontab w poleceniu i podania pliku. Jeśli katalog jest udostępniany w sieci, często używam go
crontab.$(hostname)
jako nazwy pliku. To ostatecznie usunie przypadki, w których niewłaściwy plik crontab zostanie załadowany na niewłaściwy serwer.Użycie pliku zapewnia kopię zapasową pliku crontab i pozwala na tymczasowe modyfikacje (tylko raz używam
crontab -e
automatyczne wycofanie ). Dostępne są nagłówki, które pomagają w prawidłowym ustawieniu parametrów planowania. Dodałem je, gdy niedoświadczeni użytkownicy będą edytować plik crontab.Rzadko natrafiłem na polecenia wymagające danych wejściowych użytkownika. Te zawodzą pod crontabem, chociaż niektóre będą działać z przekierowaniem danych wejściowych.
źródło
30 23 * * *
tłumaczy do 23:15?15 23 * * *
. Poprawione teraz.Jeśli uzyskujesz dostęp do konta za pomocą kluczy SSH, możesz zalogować się na konto, ale nie zauważyć, że hasło do konta jest zablokowane (np. Z powodu wygaśnięcia lub niepoprawnych prób hasła)
Jeśli system używa PAM, a konto jest zablokowane, może to uniemożliwić uruchomienie usługi cronjob. (Przetestowałem to na Solarisie, ale nie na Ubuntu)
Takie wiadomości możesz znaleźć w / var / adm / messages:
Wszystko, co musisz zrobić, to uruchomić:
jako root, aby odblokować konto, a crontab powinien znów działać.
źródło
Jeśli masz takie polecenie:
i nie działa i nie widać żadnych danych wyjściowych, niekoniecznie musi to oznaczać, że cron nie działa. Skrypt może zostać uszkodzony, a wynik przechodzi do stderr, który nie jest przekazywany do / tmp / output. Sprawdź, czy tak nie jest, przechwytując również te dane wyjściowe:
aby sprawdzić, czy to pomoże Ci rozwiązać problem.
źródło
=== Alert Docker ===
Jeśli używasz dokera,
Myślę, że warto dodać, że nie udało mi się sprawić, aby cron działał w tle.
Aby uruchomić zadanie CRON w kontenerze, użyłem nadzorcy i uruchomiłem
cron -f
razem z innym procesem.Edycja: Kolejny problem - nie udało mi się również uruchomić go podczas uruchamiania kontenera z siecią HOST. Zobacz ten problem tutaj również: https://github.com/phusion/baseimage-docker/issues/144
źródło
Pisałem skrypt powłoki instalacyjnej, który tworzy kolejny skrypt usuwający stare dane transakcji z bazy danych. W ramach zadania musiała skonfigurować codzienne
cron
zadanie do uruchomienia w dowolnym momencie, gdy obciążenie bazy danych było niskie.Utworzyłem plik
mycronjob
z harmonogramem cron, nazwą użytkownika i poleceniem i skopiowałem go do/etc/cron.d
katalogu. Moje dwie gotcha:mycronjob
plik musiał być własnością roota, aby uruchomićProblem z uprawnieniami pojawi się
/var/log/syslog
jako coś podobnego do:Pierwszy wiersz odnosi się do
/etc/crontab
pliku, a później do pliku, pod którym umieściłem/etc/cront.d
.źródło
Linia napisana w sposób, którego crontab nie rozumie. To musi być poprawnie napisane. Oto CrontabHowTo .
źródło
Demon Cron może być uruchomiony, ale w rzeczywistości nie działa. Spróbuj zrestartować crona:
źródło
pidof
crona i nic nie dostałem. Próbowałem użyćservice
narzędzia i powiedziałem, że cron już działa. Po prostu uruchomiłem to polecenie i uruchomiłempidof
ponownie, a otrzymuję wynik.Zapis do crona przez „crontab -e” z argumentem nazwy użytkownika w linii. Widziałem przykłady użytkowników (lub sysadminów) piszących swoje skrypty powłoki i nie rozumiejących, dlaczego nie automatyzują. Argument „użytkownik” istnieje w / etc / crontab, ale nie w plikach zdefiniowanych przez użytkownika. na przykład twój plik osobisty wyglądałby tak:
podczas gdy / etc / crontab to:
Dlaczego więc zrobiłbyś to drugie? W zależności od tego, jak chcesz ustawić swoje uprawnienia, może to być bardzo skomplikowane. Napisałem skrypty do automatyzacji zadań dla użytkowników, którzy nie rozumieją zawiłości lub nie chcą zawracać sobie głowy nudą. Ustawiając uprawnienia na
--x------
, mogę sprawić, że skrypt będzie wykonywalny bez ich możliwości odczytu (i być może przypadkowej zmiany). Mogę jednak chcieć uruchomić to polecenie z kilkoma innymi z jednego pliku (ułatwiając w ten sposób utrzymanie), ale upewnij się, że dane wyjściowe pliku mają przypisanego właściwego właściciela. Takie postępowanie (przynajmniej w Ubuntu 10.10) zakłóca zarówno niemożność odczytania pliku, jak i jego wykonania, a także wspomniany wcześniej problem z umieszczaniem kropek w / etc / crontab (co, co zabawne, nie powoduje błędów podczas przejściacrontab -e
) .Jako przykład widziałem przypadki
sudo crontab -e
użycia skryptu z uprawnieniami roota, z odpowiednimchown username file_output
w skrypcie powłoki. Niechlujny, ale działa. IMHO, bardziej wdzięczną opcją jest umieszczenie go/etc/crontab
z zadeklarowaną nazwą użytkownika i odpowiednimi uprawnieniami, więcfile_output
trafia we właściwe miejsce i właściciela.źródło
Opierając się na tym, o czym wspomniał Aaron Peart na temat trybu pełnego, czasami skrypty nie w trybie pełnym są inicjalizowane, ale nie kończą się, jeśli domyślnym zachowaniem zawartej komendy jest wyświetlanie linii lub więcej na ekranie po uruchomieniu proc. Na przykład napisałem skrypt kopii zapasowej dla naszego intranetu, który używał curl, narzędzia, które pobiera lub przesyła pliki na zdalne serwery, i jest całkiem przydatne, jeśli możesz uzyskać dostęp do tych zdalnych plików tylko przez HTTP. Użycie „curl http://something.com/somefile.xls ” spowodowało, że skrypt, który napisałem, zawiesił się i nigdy nie ukończył, ponieważ wyrzuca nowy wiersz, po którym następuje linia postępu. Musiałem użyć cichej flagi (-s), aby powiedzieć jej, aby nie wyświetlała żadnych informacji, i napisać własny kod, aby obsłużyć, jeśli pobieranie pliku nie powiedzie się.
źródło
/dev/null
. Na przykład:some-command > /dev/null
przekieruje tylko standardowe wyjście, a nie wyjście błędu (co zwykle jest tym, czego chcesz, ponieważ chcesz być informowany o błędach). Aby przekierować również wyjście błędu, użyjsome-command &> /dev/null
.Chociaż możesz definiować zmienne środowiskowe w swoim crontable, nie jesteś w skrypcie powłoki. Zatem konstrukcje takie jak poniższe nie będą działać:
Wynika to z faktu, że zmienne nie są interpretowane w tabeli crontable: wszystkie wartości są przyjmowane literalnie. I to samo, jeśli pominiesz nawiasy. Twoje polecenia nie będą działać, a pliki dziennika nie zostaną zapisane ...
Zamiast tego musisz zdefiniować wszystkie zmienne środowiskowe prosto:
źródło
Kiedy zadanie jest uruchamiane w cronie, standardowe wejście jest zamknięte. Programy, które działają inaczej w zależności od tego, czy standardowe wejście jest dostępne, czy nie, będą zachowywać się inaczej w sesji powłoki i w cronie.
Przykładem jest program
goaccess
do analizy plików dziennika serwera WWW. To NIE działa w cronie:i
goaccess
pokazuje stronę pomocy zamiast tworzenia raportu. W skorupce można to odtworzyć za pomocąRozwiązaniem
goaccess
jest zmusić go do odczytu dziennika ze standardowego wejścia zamiast odczytu z pliku, więc rozwiązaniem jest zmiana wpisu crontab naźródło
W moim przypadku cron i crontab mieli różnych właścicieli.
NIE działa Miałem to:
Zasadniczo musiałem uruchomić cron-config i poprawnie odpowiedzieć na pytania. Jest punkt, w którym musiałem wprowadzić hasło użytkownika Win7 do mojego konta „Użytkownik”. Po przeczytaniu zrobiłem, wygląda na to, że jest to potencjalny problem bezpieczeństwa, ale jestem jedynym administratorem w jednej sieci domowej, więc zdecydowałem, że jest OK.
Oto sekwencja poleceń, która mnie uruchomiła:
źródło
Na moich serwerach RHEL7 działałyby zadania root cron, ale zadania użytkownika nie. Odkryłem, że bez katalogu domowego zadania nie będą działać (ale zobaczysz dobre błędy w / var / log / cron). Kiedy utworzyłem katalog domowy, problem został rozwiązany.
źródło
Jeśli edytujesz plik crontab przy użyciu edytora systemu Windows (przez sambę lub coś takiego) i zastąpiono go nowymi wierszami \ n \ r lub po prostu \ r, cron nie uruchomi się.
Ponadto, jeśli używasz /etc/cron.d/* i jeden z tych plików zawiera \ r, cron będzie przechodził między plikami i zatrzyma się, gdy trafi na zły plik. Nie jesteś pewien, czy to jest problem?
Posługiwać się:
źródło