Tarkibga o'tish

crontab va tizim cron’i

cron asoslari maqolasida crontab qatorining besh maydonli vaqt sintaksisi ko'rib chiqildi. Keyingi savol amaliyroq: bunday qatorni amalda qanday o'rnatasiz, uni qayerda ko'rish yoki olib tashlash mumkin, oddiy foydalanuvchining crontab’i tizim darajasida ishlaydigan cron’dan nimasi bilan farq qiladi? Bu farqni bilmaslik amaliyotdagi eng ko'p uchraydigan chalkashlik manbalaridan biri. Vazifa "cron’da yo'q"dek ko'rinadi, holbuki aslida u butunlay boshqa foydalanuvchi akkaunti ostida yozilgan bo'ladi.

Nimalarni o'rganasiz

Bu maqola oxirida siz quyidagilarni qila olasiz:

  • crontab buyrug'ining -e, -l, -r va -u flag'laridan foydalanish;
  • foydalanuvchi crontab’i qayerda saqlanishini va uni to'g'ridan-to'g'ri tahrirlash nega tavsiya etilmasligini tushuntirish;
  • tizim darajasidagi crontab’lar — /etc/crontab va /etc/cron.d/ — ni foydalanuvchining shaxsiy crontab’idan farqlash;
  • /etc/cron.daily/ kabi kataloglarni va run-parts ularni qanday bajarishini tushuntirish;
  • cron.allow va cron.deny yordamida cron’dan umuman kim foydalana olishini boshqarish.

Foydalanuvchi crontab’i: crontab buyrug'i

Har bir foydalanuvchi o'z crontab’ini faylni to'g'ridan-to'g'ri ochib emas, crontab buyrug'i orqali boshqaradi. Chunki bu buyruq saqlangan zahoti cron daemon’iga jadval o'zgarganini bildiradi.

crontab -e

Bu buyruq $EDITOR (yoki $VISUAL) muhit o'zgaruvchisida ko'rsatilgan muharrirni ochadi. Agar ikkalasi ham o'rnatilmagan bo'lsa, tizim odatda nano ga o'tadi yoki tanlash menyusini taklif qiladi:

echo $EDITOR

export EDITOR=nano
crontab -e

Quyidagi qatorni qo'shing va saqlang:

0 7 * * 1 /home/<username>/scripts/weekly-report.sh

Tekshirish:

crontab -l
0 7 * * 1 /home/<username>/scripts/weekly-report.sh

crontab -l joriy foydalanuvchining faol crontab’ini ekranga chiqaradi. Fayl diskda qayerda turganini bilish shart emas, chunki u hech qachon to'g'ridan-to'g'ri ochilmaydi.

Foydalanuvchi crontab’i qayerda saqlanadi

sudo ls -l /var/spool/cron/crontabs/
-rw------- 1 <username> crontab 68 Jul 26 09:15 <username>

Har bir foydalanuvchi uchun 600 ruxsatli alohida fayl bo'ladi — uni faqat egasi (va root) o'qiy oladi. Bu faylni to'g'ridan-to'g'ri tahrirlash tavsiya etilmaydi. crontab -e faylni saqlashdan oldin uning sintaksisini tekshiradi, faylni to'g'ridan-to'g'ri tahrirlash esa bu tekshiruvni butunlay chetlab o'tadi. Noto'g'ri tuzilgan crontab’ni esa daemon jimgina e’tiborsiz qoldirishi mumkin.

Boshqa foydalanuvchining crontab’ini boshqarish

sudo crontab -u www-data -l

-u flag'i administratorga sudo orqali boshqa foydalanuvchining crontab’ini ko'rish yoki tahrirlash imkonini beradi. Bu o'zlari interaktiv tarzda tizimga kira olmaydigan servis akkauntlari (www-data, postgres va shunga o'xshashlar) uchun keng tarqalgan.

Crontab’ni tozalash

crontab -r

-r joriy foydalanuvchining barcha cron vazifalarini tasdiq so'ramasdan, darhol o'chiradi.

crontab -r ni qaytarib bo'lmaydi

Tanlab o'chirish imkoni yo'q — butun fayl birdaniga yo'qoladi. Bitta vazifani olib tashlash uchun crontab -e ni ochib, o'sha qatorni qo'lda o'chiring yoki uni vaqtincha o'chirib qo'yish uchun boshiga # qo'yib izohga aylantiring. -r ni ishga tushirishdan oldin, ayniqsa production serverda, avval joriy holatni saqlab qo'ying: crontab -l > ~/crontab-backup-$(date +%F).txt.

Tizim darajasidagi cron: /etc/crontab

Foydalanuvchilarning shaxsiy crontab’lari bilan bir qatorda butun tizim uchun yagona umumiy jadval fayli ham bor:

cat /etc/crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )

Asosiy farq darhol ko'zga tashlanadi — bu yerda oltinchi ustun bor. Foydalanuvchi crontab’ida buyruq vaqt maydonlaridan keyin darhol keladi. /etc/crontab da esa vaqt maydonlaridan keyin buyruq qaysi foydalanuvchi nomidan ishlashi (yuqoridagi misolda root) yoziladi, shundan keyingina buyruqning o'zi keladi.

Xususiyat Foydalanuvchi crontab’i (crontab -e) /etc/crontab
Kim tahrirlaydi Har bir foydalanuvchi o'zinikini Faqat root
Ustunlar soni 5 ta vaqt maydoni + buyruq 5 ta vaqt maydoni + foydalanuvchi + buyruq
Qaysi foydalanuvchi nomidan ishlaydi Har doim egasi Qatorda ko'rsatilgan foydalanuvchi
Qanday o'rnatiladi crontab -e uni avtomatik qayta yuklaydi Faylni saqlash yetarli, alohida buyruq kerak emas
Odatiy qo'llanilishi Shaxsiy yoki loyihaga xos vazifalar Tizim darajasidagi vazifalar, ko'pincha paketlar o'rnatadi

/etc/cron.d/: paketlar uchun alohida fayllar

/etc/crontab ni to'g'ridan-to'g'ri tahrirlash o'rniga odatda /etc/cron.d/ ga alohida fayl qo'shiladi. Bu paketga umumiy faylga tegmasdan o'z jadvalini o'rnatish yoki yangilash imkonini beradi:

sudo nano /etc/cron.d/backup-check
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

30 3 * * * root /usr/local/bin/backup-check.sh

/etc/cron.d/ dagi fayllar /etc/crontab bilan bir xil olti ustunli formatdan foydalanadi, lekin ular crontab -e orqali o'tmaydi. Faylni to'g'ridan-to'g'ri yaratish yoki tahrirlash yetarli, chunki cron daemon bu katalogni doimiy kuzatib turadi.

/etc/cron.daily/ va shunga o'xshash kataloglar

Ko'plab tizim skriptlari (masalan, logrotate va paket menejerining avtomatik tozalash vazifalari) aniq vaqt yozish o'rniga tayyor kataloglarga joylashtiriladi:

ls /etc/cron.daily/ /etc/cron.weekly/ /etc/cron.monthly/
/etc/cron.daily/:
apt-compat  dpkg  logrotate

/etc/cron.weekly/:
man-db

/etc/cron.monthly/:
0anacron

Bu kataloglardagi har bir fayl — bajariladigan skript. Ularni kerakli vaqtda amalda ishga tushiradigan mexanizm — yuqoridagi /etc/crontab misolida ko'rinib turgan run-parts:

run-parts --test /etc/cron.daily

run-parts --test qaysi skriptlar ishga tushirilishini ularni haqiqatan bajarmasdan ko'rsatadi. --report (yuqoridagi /etc/crontab misolida ko'rilgan) esa unga har bir skript natijasi haqida qisqa hisobot yozdiradi.

Bu kataloglar aniq daqiqa emas, taxminiy vaqt ("kuniga bir marta, ertalab") kifoya qiladigan vazifalar uchun qulay. Aniqlik muhim bo'lmaganda skriptni /etc/cron.daily/ ga tashlab qo'yish /etc/cron.d/ da to'liq qator yozishdan oddiyroq.

Fayl nomidagi jimjit tuzoq: nuqta ham, kengaytma ham bo'lmasin

/etc/cron.d/ (cron uni to'g'ridan-to'g'ri o'qiydi) ham, run-parts kataloglari (/etc/cron.daily/ va uning qardoshlari) ham nomida . bor har qanday faylni e’tiborsiz qoldiradi — umuman olganda, [A-Za-z0-9_-] dan tashqari belgilar bor har qanday nomni. backup-check.sh yoki backup.check nomi bilan tashlab qo'yilgan fayl hech qayerda xato yozilmasdan o'tkazib yuboriladi. Xuddi shu fayl backup-check deb qayta nomlansa, ishlaydi. "/etc/cron.d/ dagi vazifam shunchaki ishlamayapti va log'da hech narsa chiqmayapti" holatining eng keng tarqalgan sababi aynan shu. Yuqorida yaratilgan drop-in fayl ham aynan shuning uchun backup-check.sh emas, backup-check deb nomlangan. run-parts kataloglariga joylashtirilgan skriptlar bundan tashqari bajariladigan (chmod +x) va root ga tegishli bo'lishi kerak. Mavjud, lekin bajarilmaydigan skript ham xuddi shunday jimgina o'tkazib yuboriladi.

anacron

Ko'plab zamonaviy tizimlarda bu kataloglarni anacron boshqaradi. U har doim yoqilib turmaydigan mashinalar (masalan, noutbuk) uchun mo'ljallangan va o'tkazib yuborilgan vazifani tizim navbatdagi safar ishga tushganda bajaradi. Doim ishlab turadigan serverda bu farq amalda kamdan-kam ahamiyatga ega.

cron’dan kim foydalana oladi: cron.allow va cron.deny

Ko'p foydalanuvchili serverda har bir akkaunt o'z vazifalarini rejalashtira olishi har doim ham ma’qul emas. Buni ikkita ixtiyoriy fayl boshqaradi:

cat /etc/cron.allow 2>/dev/null
cat /etc/cron.deny 2>/dev/null

Mantiq quyidagicha ishlaydi:

  • agar /etc/cron.allow mavjud bo'lsa — crontab dan faqat unda ko'rsatilgan foydalanuvchilar foydalana oladi, qolganlarga rad javobi beriladi;
  • agar /etc/cron.allow mavjud bo'lmasa-yu, /etc/cron.deny mavjud bo'lsa — unda ko'rsatilganlardan tashqari hamma foydalana oladi;
  • agar ikkalasi ham mavjud bo'lmasa (Ubuntu’da standart holat) — har bir foydalanuvchi cron’dan foydalana oladi.
sudo nano /etc/cron.deny
guest
tempuser

Bu, masalan, vaqtinchalik yoki mehmon akkauntlarining o'z avtomatik vazifalarini qo'shishiga yo'l qo'ymaslikning oddiy usuli.

Amaliy vaziyat: servis akkaunti ostidagi rejalashtirilgan vazifa

Muammo. www-data ga tegishli ilova katalogi uchun har kuni ertalab soat 4:00 da tozalash vazifasi kerak. Lekin www-data interaktiv tarzda tizimga kira olmaydi, shuning uchun crontab -e ni to'g'ridan-to'g'ri shu foydalanuvchi nomidan ishga tushirib bo'lmaydi.

Yechim — boshqa foydalanuvchining crontab’ini sudo -u uslubidagi kirish bilan tahrirlash:

sudo crontab -u www-data -e
0 4 * * * find /var/www/myapp/tmp -type f -mtime +1 -delete

Tekshirish:

sudo crontab -u www-data -l
0 4 * * * find /var/www/myapp/tmp -type f -mtime +1 -delete
sudo ls -l /var/spool/cron/crontabs/www-data
-rw------- 1 www-data crontab 58 Jul 26 09:20 www-data

Xulosa. Vazifa www-data ga tegishli fayllar bilan to'g'ri ishlaydi, chunki u aynan shu foydalanuvchi nomidan bajariladi. Agar buyruq shaxsiy crontab’ga joylashtirilganida, find ... -delete ga www-data fayllariga tegish uchun ruxsat yetmay qolishi mumkin edi.

Keng tarqalgan xatolar

  • sudo crontab -e ni crontab -e bilan chalkashtirish. sudo crontab -e joriy foydalanuvchining emas, rootning crontab’ini tahrirlaydi. Boshqa foydalanuvchining crontab’ini tahrirlash uchun uni -u bilan aniq ko'rsating (sudo crontab -u <username> -e).
  • /var/spool/cron/crontabs/ ni to'g'ridan-to'g'ri tahrirlash. Bu faylni crontab buyrug'i boshqaradi. Uni matn muharririda to'g'ridan-to'g'ri ochish — hatto sintaksis to'g'ri bo'lsa ham — cron daemon’ini fayl o'zgarganidan bexabar qoldirishi mumkin, chunki daemon odatda o'zgarishlar crontab buyrug'i orqali kelishini kutadi.
  • /etc/crontab ga foydalanuvchi ustunisiz qator qo'shish. Agar /etc/crontab yoki /etc/cron.d/ dagi qatorda, foydalanuvchi crontab’idagi kabi, faqat beshta vaqt maydoni bo'lsa, cron foydalanuvchi nomi kutilgan oltinchi ustunni buyruqning bir qismi deb talqin qiladi va vazifa mo'ljallanganidek ishlamaydi.

Mashqlar

  1. crontab -e yordamida o'z foydalanuvchi akkauntingiz ostida har kuni soat 6:00 da date >> ~/cron-test.log ni ishga tushiradigan vazifa qo'shing. Uni crontab -l bilan tekshiring, keyin crontab -e bilan olib tashlang.
  2. Hozir /etc/cron.daily/ da mavjud skriptlar ro'yxatini chiqaring va uni run-parts --test /etc/cron.daily chiqishi bilan taqqoslang.
  3. Tizimingizda cron.allow va cron.deny mavjudligini tekshiring va ikkalasi ham bo'lmaganda standart xatti-harakat qanday bo'lishini yozma tushuntiring.
  4. Faraziy deploy servis akkaunti uchun uning crontab’ini tahrirlash uchun ochadigan buyruqni yozing (uni haqiqatan ishga tushirmasdan).

Xulosa

crontab uch darajada mavjud: foydalanuvchining shaxsiy crontab’i (crontab -e), /etc/crontab va /etc/cron.d/ dagi tizim darajasidagi jadvallar hamda /etc/cron.daily/ kabi tayyor kataloglar. Ularning har biri kim tahrirlashi, qaysi foydalanuvchi nomidan ishlashi va odatda nima uchun ishlatilishi bilan farq qiladi. Agar vazifa "cron’da yo'q" bo'lsa, birinchi navbatda eng oddiy narsani tekshirish kerak — u aslida kimning crontab’iga qo'shilgan. Keyingi maqola, cron muhiti va log'lari, teskari muammoni ko'rib chiqadi: vazifa to'g'ri ro'yxatdan o'tgan, lekin kutilganidek ishlamaydi, chunki cron muhiti interaktiv terminal muhitidan farq qiladi.

Manbalar