Executarea manuală a unei sarcini cron / simularea executării unei sarcini cron? [duplicat] (Unix, Cron)

stefan.at.wpf a intrebat.

Vreau să testez dacă chestiile de trimitere prin poștă ale lui cron după o sarcină executată și lucruri de genul acesta funcționează. Există o modalitate mai elegantă de a testa acest lucru, apoi setarea unui cron job pentru a rula la fiecare câteva secunde? Așadar, există vreo modalitate de a simula execuția unui cron job / de a porni un cron job manual, dar cu același comportament pe care l-ar avea atunci când ar fi executat automat de cron?

Comentarii

  • Există o soluție mai bună la serverfault.com/q/85893/75968 –  > Por cweiske.
  • Acest lucru este, de asemenea, discutat pe Ask Ubuntu: „Verifică dacă crontab funcționează” –  > Por Wildcard.
3 răspunsuri
Gilles ‘SO- nu mai fi rău’

Principala diferență între executarea unui job cron pe linia de comandă și în interiorul cron este mediul său. Alte potențiale diferențe includ directorul curent, disponibilitatea unui terminal și ce shell este utilizat.

Aceasta este o simulare destul de precisă a executării unui job cron prin cron. Pentru a evita diferențele datorate shell-ului, plasați-vă sarcina într-un script și puneți în crontab doar calea către acel script. Rețineți că setul și valorile exacte ale variabilelor de mediu transmise de cron depind de implementare; verificați fișierul crontab(5) pagina de manual de pe sistemul dumneavoastră. ifne este o comandă care execută comanda specificată în argumente dacă primește anumite intrări; există una în moreutils.

env -i HOME="$HOME" LOGNAME="$LOGNAME" PATH=/usr/bin:/bin SHELL=/bin/sh USER="$USER" 
    /path/to/script </dev/null 2>&1 |
ifne mail -r "Cron Daemon" -s "Cron <[email protected]$(hostname)> /path/to/script" "$USER"

O altă modalitate de a crea o setare de tip cron este prin at. Dar at se ocupă de rularea comenzii cu variabilele de mediu pe care at proces a primit, așa că trebuie să emulați această parte.

echo /path/to/script |
env -i HOME="$HOME" LOGNAME="$LOGNAME" PATH=/usr/bin:/bin SHELL=/bin/sh USER="$USER" 
    at now

Louis

Iată cum am procedat pentru a simula executarea cron a unui script pe care l-am creat cu ani în urmă, dar care a început să dea greș de curând.

Am creat un script numit dumpenv:

#!/bin/sh

base=$(basename $0)

env -0 > /tmp/$base.$$.dump

Acesta descarcă toate variabilele de mediu într-un fișier în /tmp/. Apoi mi-am modificat crontab-ul pentru a adăuga:

*/1 * * * *  [path to newly created script]

Acest lucru face ca scriptul să ruleze la fiecare minut. Astfel, după un minut, am obținut o copie a mediului văzut de sarcinile rulate din cron. Dacă linia crontab este lăsată să ruleze mai mult de un minut, aceasta creează o grămadă de fișiere identice cu nume care diferă doar prin partea pid a numelui fișierului ($$). Nu e mare lucru. Aș fi putut codifica pentru această eventualitate, astfel încât să obțin un singur fișier, dar principiul principal aici este „suficient de bun”, și s-ar putea să vreau să folosesc dumpenv în alte contexte în care sunt utile mai multe descărcări. În orice caz, este recomandabil să se elimine linia crontab care a fost adăugată pentru a evita popularea /tmp cu o mulțime de gunoaie.

Apoi am creat un fișier suplimentar pe care l-am numit /tmp/command care conținea comanda pe care doream să o execut, pe o singură linie terminată cu un caracter nul. Caracterul null este necesar.

Apoi am lansat:

cat [path to dumpfile crated earlier] /tmp/command | xargs -0 -x env -i

Și acest lucru a replicat defecțiunea pe care am văzut-o atunci când comanda mea este executată din cron. Ceea ce xargs face este să construiască o comandă de forma:

env -i [list of environment variables] [command to execute]

și o execută. Lista variabilelor de mediu provine din fișierul de vidare. Comanda care env execută provine din fișierul /tmp/command fișier.

Adresa -0 argumente pentru env și xargs și caracterul nul necesar pe care îl menționez mai sus au rolul de a preveni manipularea mediului în timp ce variabilele sunt transmise. În cazurile în care mediul nu conține nicio variabilă de mediu cu o linie nouă în ea, -0 ar putea fi omis din invocarea lui env în cadrul dumpenv și din scriptul xargs și comanda /tmp/command nu ar necesita un caracter null ca și terminator de linie.

Nu fac o redirecționare explicită a stdin către /dev/null, deoarece xargs o face pentru mine. De asemenea, nu mă interesează redirecționarea stdout/stderr și nu doresc să primesc un e-mail dacă comanda eșuează. Pentru cazurile în care aceste caracteristici sunt dorite, răspunsul lui Gilles oferă mijloacele de a face acest lucru.

allnatural

Răspunsul lui Louis este grozav. Propun o mică îmbunătățire posibilă.

În loc de a crea un fișier /tmp/command care să conțină calea către scriptul pe care doriți să îl executați, așa cum a sugerat Louis, în următorul cod:

cat [path to dumpfile crated earlier] /tmp/command | xargs -0 -x env -i

În schimb, puteți numi scriptul direct în comandă prin intermediul următoarei comenzi alternative (luați aminte la x00 adăugat la calea scriptului cron, care este esențială:

printf "/path/to/cron/scriptx00" | cat /path/to/dumpfile/created/earlier - | xargs -0 -x env -i

Astfel se evită orice nevoie de a crea un fișier /tmp/command.

Comentarii

  • Notă: Mi-am editat postarea inițială deoarece am găsit o soluție mai curată (folosind printf în loc de awk) –  > Por allnatural.

Tags: