लिनक्समध्ये क्रोन: इतिहास, वापर आणि डिव्हाइस

लिनक्समध्ये क्रोन: इतिहास, वापर आणि डिव्हाइस

क्लासिकने लिहिले की आनंदी तास पहात नाहीत. त्या जंगली काळात प्रोग्रामर किंवा युनिक्स नव्हते, परंतु आज प्रोग्रामरना निश्चितपणे माहित आहे: क्रॉन त्यांच्याऐवजी वेळेचा मागोवा ठेवेल.

कमांड लाइन युटिलिटिज माझ्यासाठी कमकुवतपणा आणि काम आहे. sed, awk, wc, cut आणि इतर जुने प्रोग्राम आमच्या सर्व्हरवर दररोज स्क्रिप्टद्वारे चालवले जातात. त्यापैकी बरेच क्रॉनसाठी कार्य म्हणून डिझाइन केले आहेत, मूळतः 70 च्या दशकातील शेड्यूलर.

बर्‍याच काळासाठी मी तपशीलात न जाता, वरवरच्या क्रॉनचा वापर केला, परंतु एके दिवशी, जेव्हा स्क्रिप्ट चालवताना मला त्रुटी आली, तेव्हा मी त्याकडे पूर्णपणे लक्ष देण्याचा निर्णय घेतला. हा लेख अशाप्रकारे दिसला, तो लिहिताना मला POSIX क्रॉन्टॅब, लोकप्रिय लिनक्स वितरणातील मुख्य क्रॉन पर्याय आणि त्यातील काहींच्या संरचनेची ओळख झाली.

तुम्ही लिनक्स वापरत आहात आणि क्रॉन टास्क चालवत आहात? तुम्हाला युनिक्समधील सिस्टम अॅप्लिकेशन आर्किटेक्चरमध्ये स्वारस्य आहे का? मग आम्ही आमच्या मार्गावर आहोत!

सामग्री

प्रजातींचे मूळ

सर्व ऑपरेटिंग सिस्टीममध्ये वापरकर्ता किंवा सिस्टम प्रोग्राम्सची नियतकालिक अंमलबजावणी ही एक स्पष्ट गरज आहे. म्हणून, प्रोग्रामरना अशा सेवांची आवश्यकता जाणवली जी त्यांना मध्यवर्ती योजना आणि कार्ये कार्यान्वित करण्यास अनुमती देतात.

युनिक्स सारखी ऑपरेटिंग सिस्टीम त्यांची उत्पत्ती आवृत्ती 7 युनिक्स पर्यंत शोधून काढतात, गेल्या शतकाच्या 70 च्या दशकात बेल लॅबमध्ये विकसित केली गेली होती, ज्यात प्रसिद्ध केन थॉम्पसन यांचा समावेश आहे. आवृत्ती 7 युनिक्समध्ये क्रॉन देखील समाविष्ट आहे, जी सुपरयुजर टास्क नियमितपणे चालवणारी सेवा आहे.

एक सामान्य आधुनिक क्रॉन हा एक साधा प्रोग्राम आहे, परंतु मूळ आवृत्तीचा ऑपरेटिंग अल्गोरिदम आणखी सोपा होता: सेवा मिनिटातून एकदा उठते, एकाच फाईलमधील कार्यांसह टेबल वाचते (/etc/lib/crontab) आणि त्यासाठी केले जाते. सुपरयुजर ती कार्ये जी सध्याच्या क्षणी केली जावीत.

त्यानंतर, सर्व युनिक्स सारख्या ऑपरेटिंग सिस्टीमसह साध्या आणि उपयुक्त सेवेच्या सुधारित आवृत्त्या पुरवल्या गेल्या.

क्रॉन्टॅब फॉरमॅटचे सामान्यीकृत वर्णन आणि युटिलिटीच्या ऑपरेशनची मूलभूत तत्त्वे 1992 मध्ये युनिक्स-सदृश ऑपरेटिंग सिस्टमच्या मुख्य मानक - POSIX - मध्ये समाविष्ट केली गेली आणि अशा प्रकारे डी फॅक्टो स्टँडर्डमधून क्रॉन एक डी ज्युअर मानक बनले.

1987 मध्ये, पॉल विक्सी, युनिक्स वापरकर्त्यांचे क्रॉनसाठी त्यांच्या इच्छेबद्दल सर्वेक्षण करून, डिमनची दुसरी आवृत्ती जारी केली ज्याने पारंपारिक क्रॉनच्या काही समस्या दुरुस्त केल्या आणि टेबल फाइल्सची वाक्यरचना विस्तृत केली.

Vixie cron च्या तिसऱ्या आवृत्तीने POSIX आवश्यकता पूर्ण करण्यास सुरुवात केली, त्याव्यतिरिक्त, प्रोग्रामला उदारमतवादी परवाना होता, किंवा त्याऐवजी README मधील इच्छा वगळता कोणताही परवाना नव्हता: लेखक हमी देत ​​​​नाही, लेखकाचे नाव हटविले जाऊ शकत नाही, आणि प्रोग्राम फक्त स्त्रोत कोडसह विकला जाऊ शकतो. या आवश्यकता फ्री सॉफ्टवेअरच्या तत्त्वांशी सुसंगत असल्याचे दिसून आले जे त्या वर्षांमध्ये लोकप्रिय होत होते, म्हणून 90 च्या दशकाच्या सुरुवातीस दिसणार्‍या काही प्रमुख Linux वितरणांनी Vixie क्रॉनला त्यांची प्रणाली म्हणून घेतले आणि आजही ते विकसित करत आहेत.

विशेषतः, Red Hat आणि SUSE ने Vixie cron - cronie चा एक काटा विकसित केला आणि डेबियन आणि Ubuntu अनेक पॅचसह Vixie cron ची मूळ आवृत्ती वापरतात.

चला प्रथम POSIX मध्ये वर्णन केलेल्या वापरकर्ता युटिलिटी क्रॉन्टॅबशी परिचित होऊ या, त्यानंतर आपण विक्सी क्रॉनमध्ये प्रदान केलेले वाक्यरचना विस्तार आणि लोकप्रिय लिनक्स वितरणांमध्ये विक्सी क्रॉनच्या भिन्नतेचा वापर पाहू. आणि शेवटी, केकवरील चेरी क्रॉन डिमन उपकरणाचे विश्लेषण आहे.

POSIX क्रॉन्टॅब

जर मूळ क्रॉन नेहमी सुपरयुजरसाठी काम करत असेल, तर आधुनिक शेड्युलर सहसा सामान्य वापरकर्त्यांच्या कार्यांना सामोरे जातात, जे अधिक सुरक्षित आणि सोयीस्कर असतात.

क्रॉन्स दोन प्रोग्राम्सच्या संचाच्या रूपात पुरवले जातात: सतत चालू असलेले क्रॉन डिमन आणि वापरकर्त्यांसाठी उपलब्ध क्रॉनटॅब उपयुक्तता. नंतरचे तुम्हाला सिस्टममधील प्रत्येक वापरकर्त्यासाठी विशिष्ट टास्क टेबल्स संपादित करण्याची परवानगी देते, तर डिमन वापरकर्ता आणि सिस्टम टेबलमधून कार्ये लाँच करते.

В POSIX मानक डिमनच्या वर्तनाचे वर्णन कोणत्याही प्रकारे केले जात नाही आणि केवळ वापरकर्ता प्रोग्राम औपचारिक केला जातो क्रॉन्टाब. वापरकर्ता कार्ये लाँच करण्यासाठी यंत्रणेचे अस्तित्व अर्थातच निहित आहे, परंतु तपशीलवार वर्णन केलेले नाही.

क्रॉन्टॅब युटिलिटीला कॉल करून, तुम्ही चार गोष्टी करू शकता: एडिटरमध्ये वापरकर्त्याचे टास्क टेबल संपादित करा, फाइलमधून टेबल लोड करा, सध्याचे टास्क टेबल दाखवा आणि टास्क टेबल साफ करा. क्रॉन्टॅब युटिलिटी कशी कार्य करते याची उदाहरणे:

crontab -e # редактировать таблицу задач
crontab -l # показать таблицу задач
crontab -r # удалить таблицу задач
crontab path/to/file.crontab # загрузить таблицу задач из файла

फोन केला असता crontab -e मानक पर्यावरण व्हेरिएबलमध्ये निर्दिष्ट केलेला संपादक वापरला जाईल EDITOR.

कार्ये स्वतः खालील स्वरूपात वर्णन केली आहेत:

# строки-комментарии игнорируются
#
# задача, выполняемая ежеминутно
* * * * * /path/to/exec -a -b -c
# задача, выполняемая на 10-й минуте каждого часа
10 * * * * /path/to/exec -a -b -c
# задача, выполняемая на 10-й минуте второго часа каждого дня и использующая перенаправление стандартного потока вывода
10 2 * * * /path/to/exec -a -b -c > /tmp/cron-job-output.log

रेकॉर्डची पहिली पाच फील्ड: मिनिटे [1..60], तास [0..23], महिन्याचे दिवस [1..31], महिने [1..12], आठवड्याचे दिवस [0. .6], जिथे 0 रविवार आहे. शेवटची, सहावी, फील्ड ही एक ओळ आहे जी मानक कमांड इंटरप्रिटरद्वारे कार्यान्वित केली जाईल.

पहिल्या पाच फील्डमध्ये, मूल्ये स्वल्पविरामाने विभक्त केली जाऊ शकतात:

# задача, выполняемая в первую и десятую минуты каждого часа
1,10 * * * * /path/to/exec -a -b -c

किंवा हायफनसह:

# задача, выполняемая в каждую из первых десяти минут каждого часа
0-9 * * * * /path/to/exec -a -b -c

टास्क शेड्यूलिंगसाठी वापरकर्त्याचा प्रवेश POSIX मध्ये cron.allow आणि cron.deny फायलींद्वारे नियंत्रित केला जातो, जे क्रॉनटॅबमध्ये प्रवेश असलेल्या वापरकर्त्यांना आणि प्रोग्राममध्ये प्रवेश नसलेल्या वापरकर्त्यांची यादी करतात. मानक कोणत्याही प्रकारे या फाइल्सच्या स्थानाचे नियमन करत नाही.

मानकांनुसार, लाँच केलेल्या प्रोग्राम्ससाठी किमान चार पर्यावरणीय व्हेरिएबल्स पास करणे आवश्यक आहे:

  1. HOME - वापरकर्त्याची होम डिरेक्टरी.
  2. LOGNAME — वापरकर्ता लॉगिन.
  3. PATH हा एक मार्ग आहे जिथे तुम्ही मानक प्रणाली उपयुक्तता शोधू शकता.
  4. शेल - वापरलेल्या कमांड इंटरप्रिटरचा मार्ग.

विशेष म्हणजे, या व्हेरिएबल्सची मूल्ये कुठून येतात याबद्दल POSIX काहीही सांगत नाही.

बेस्ट सेलर - विक्सी क्रॉन 3.0pl1

लोकप्रिय क्रॉन प्रकारांचे सामान्य पूर्वज म्हणजे Vixie cron 3.0pl1, 1992 मध्ये comp.sources.unix मेलिंग लिस्टमध्ये सादर केले गेले. आम्ही या आवृत्तीच्या मुख्य वैशिष्ट्यांचा अधिक तपशीलवार विचार करू.

विक्सी क्रॉन दोन प्रोग्राम्समध्ये येतो (क्रॉन आणि क्रॉनटॅब). नेहमीप्रमाणे, डिमन सिस्टम टास्क टेबल आणि वैयक्तिक वापरकर्ता टास्क टेबलमधील टास्क वाचण्यासाठी आणि चालवण्यासाठी जबाबदार आहे आणि क्रॉन्टॅब युटिलिटी यूजर टेबल्स संपादित करण्यासाठी जबाबदार आहे.

कार्य सारणी आणि कॉन्फिगरेशन फाइल्स

सुपरयुजर टास्क टेबल /etc/crontab मध्ये स्थित आहे. सिस्टम टेबलचा सिंटॅक्स विक्सी क्रॉनच्या सिंटॅक्सशी संबंधित आहे, अपवाद वगळता त्यातील सहावा स्तंभ वापरकर्त्याचे नाव सूचित करतो ज्याच्या वतीने कार्य सुरू केले आहे:

# Запускается ежеминутно от пользователя vlad
* * * * * vlad /path/to/exec

नियमित वापरकर्ता कार्य सारणी /var/cron/tabs/username मध्ये स्थित आहेत आणि समान वाक्यरचना वापरतात. जेव्हा तुम्ही वापरकर्ता म्हणून क्रॉन्टॅब युटिलिटी चालवता, तेव्हा या फायली संपादित केल्या जातात.

क्रॉन्टॅबमध्ये प्रवेश असलेल्या वापरकर्त्यांच्या याद्या /var/cron/allow आणि /var/cron/deny फाइल्समध्ये व्यवस्थापित केल्या जातात, जिथे तुम्हाला फक्त एका वेगळ्या ओळीत वापरकर्ता नाव प्रविष्ट करणे आवश्यक आहे.

विस्तारित वाक्यरचना

पॉसिक्स क्रॉन्टॅबच्या तुलनेत, पॉल विक्सीच्या सोल्यूशनमध्ये युटिलिटीच्या टास्क टेबलच्या वाक्यरचनामध्ये अनेक अतिशय उपयुक्त बदल आहेत.

एक नवीन सारणी वाक्यरचना उपलब्ध झाली आहे: उदाहरणार्थ, तुम्ही आठवड्याचे दिवस किंवा महिने नावाने (सोम, मंगळ, आणि असे) निर्दिष्ट करू शकता:

# Запускается ежеминутно по понедельникам и вторникам в январе
* * * Jan Mon,Tue /path/to/exec

आपण कार्ये लॉन्च केलेली पायरी निर्दिष्ट करू शकता:

# Запускается с шагом в две минуты
*/2 * * * Mon,Tue /path/to/exec

चरण आणि मध्यांतर मिश्रित केले जाऊ शकतात:

# Запускается с шагом в две минуты в первых десять минут каждого часа
0-10/2 * * * * /path/to/exec

नेहमीच्या वाक्यरचनेसाठी अंतर्ज्ञानी पर्याय समर्थित आहेत (रीबूट, वार्षिक, वार्षिक, मासिक, साप्ताहिक, दैनिक, मध्यरात्री, तासाला):

# Запускается после перезагрузки системы
@reboot /exec/on/reboot
# Запускается раз в день
@daily /exec/daily
# Запускается раз в час
@hourly /exec/daily

कार्य अंमलबजावणी वातावरण

Vixie cron तुम्हाला चालू असलेल्या अनुप्रयोगांचे वातावरण बदलण्याची परवानगी देते.

USER, LOGNAME आणि HOME ही पर्यावरणीय व्हेरिएबल्स फक्त डिमनद्वारे प्रदान केलेली नाहीत, परंतु ती फाइलमधून घेतली आहेत. पासवाड. PATH व्हेरिएबल "/usr/bin:/bin" वर सेट केले आहे आणि SHELL व्हेरिएबल "/bin/sh" वर सेट केले आहे. LOGNAME वगळता सर्व व्हेरिएबल्सची मूल्ये वापरकर्ता सारण्यांमध्ये बदलली जाऊ शकतात.

काही पर्यावरण व्हेरिएबल्स (सर्वात विशेष म्हणजे SHELL आणि HOME) क्रॉनद्वारे कार्य चालवण्यासाठी वापरले जातात. सानुकूल कार्ये चालविण्यासाठी मानक sh ऐवजी bash वापरणे असे दिसते:

SHELL=/bin/bash
HOME=/tmp/
# exec будет запущен bash-ем в /tmp/
* * * * * /path/to/exec

शेवटी, सारणीमध्ये परिभाषित केलेले सर्व पर्यावरणीय चल (क्रॉनद्वारे वापरलेले किंवा प्रक्रियेद्वारे आवश्यक) चालू कार्यासाठी पास केले जातील.

फायली संपादित करण्यासाठी, क्रॉन्टॅब VISUAL किंवा EDITOR पर्यावरण व्हेरिएबलमध्ये निर्दिष्ट केलेल्या संपादकाचा वापर करते. क्रॉन्टॅब ज्या वातावरणात चालवले गेले होते तेथे हे व्हेरिएबल्स परिभाषित केले नसल्यास, "/usr/ucb/vi" वापरले जाते (यूसीबी बहुधा कॅलिफोर्निया विद्यापीठ, बर्कले आहे).

डेबियन आणि उबंटू वर क्रॉन

डेबियन आणि डेरिव्हेटिव्ह डिस्ट्रिब्युशनच्या विकसकांनी रिलीझ केले आहे अत्यंत सुधारित आवृत्ती विक्सी क्रॉन आवृत्ती 3.0pl1. टेबल फाइल्सच्या सिंटॅक्समध्ये कोणतेही फरक नाहीत; वापरकर्त्यांसाठी ते समान Vixie क्रॉन आहे. सर्वात मोठे नवीन वैशिष्ट्य: समर्थन syslog, SELinux и पीएएम.

कमी लक्षात येण्याजोगे, परंतु मूर्त बदलांमध्ये कॉन्फिगरेशन फाइल्स आणि कार्य सारण्यांचे स्थान समाविष्ट आहे.

डेबियनमधील वापरकर्ता सारण्या /var/sool/cron/crontabs निर्देशिकेत आहेत, सिस्टम टेबल अजूनही आहे - /etc/crontab मध्ये. डेबियन पॅकेज-विशिष्ट कार्य सारण्या /etc/cron.d मध्ये ठेवल्या जातात, जिथून क्रॉन डिमन आपोआप वाचतो. वापरकर्ता प्रवेश नियंत्रण हे /etc/cron.allow आणि /etc/cron.deny फाइल्सद्वारे नियंत्रित केले जाते.

डीफॉल्ट शेल अजूनही /bin/sh आहे, जे डेबियनमध्ये एक लहान POSIX-अनुरूप शेल आहे डॅश, कोणतेही कॉन्फिगरेशन न वाचता लॉन्च केले (नॉन-इंटरॅक्टिव्ह मोडमध्ये).

डेबियनच्या नवीनतम आवृत्त्यांमध्ये क्रॉन स्वतः systemd द्वारे लाँच केले गेले आहे आणि लॉन्च कॉन्फिगरेशन /lib/systemd/system/cron.service मध्ये पाहिले जाऊ शकते. सर्व्हिस कॉन्फिगरेशनमध्ये विशेष काही नाही; प्रत्येक वापरकर्त्याच्या क्रॉन्टॅबमध्ये थेट घोषित केलेल्या पर्यावरणीय व्हेरिएबल्सद्वारे कोणतेही अधिक सूक्ष्म कार्य व्यवस्थापन केले जाऊ शकते.

RedHat, Fedora आणि CentOS वर cronie

क्रोनी — विक्सी क्रॉन आवृत्ती ४.१ चा काटा. डेबियन प्रमाणे, वाक्यरचना बदललेली नाही, परंतु PAM आणि SELinux साठी समर्थन, क्लस्टरमध्ये काम करणे, inotify वापरून फाइल्स ट्रॅक करणे आणि इतर वैशिष्ट्ये जोडली गेली आहेत.

डीफॉल्ट कॉन्फिगरेशन नेहमीच्या ठिकाणी आहे: सिस्टम टेबल /etc/crontab मध्ये आहे, पॅकेजेस त्यांच्या टेबल्स /etc/cron.d मध्ये ठेवतात, वापरकर्ता टेबल्स /var/spool/cron/crontabs मध्ये जातात.

डिमन systemd नियंत्रणाखाली चालते, सर्व्हिस कॉन्फिगरेशन /lib/systemd/system/crond.service आहे.

Red Hat-सारख्या वितरणांवर, /bin/sh हे स्टार्टअपवर डीफॉल्टनुसार वापरले जाते, जे मानक बॅश आहे. हे लक्षात घ्यावे की क्रॉन जॉब्स /bin/sh द्वारे चालवताना, बॅश शेल POSIX-अनुरूप मोडमध्ये सुरू होते आणि कोणतेही अतिरिक्त कॉन्फिगरेशन वाचत नाही, नॉन-इंटरॅक्टिव्ह मोडमध्ये चालते.

SLES आणि openSUSE मध्ये cronie

जर्मन वितरण SLES आणि त्याचे डेरिव्हेटिव्ह openSUSE समान क्रोनी वापरतात. येथे डिमन देखील systemd अंतर्गत सुरू केले आहे, सेवा संरचना /usr/lib/systemd/system/cron.service मध्ये स्थित आहे. कॉन्फिगरेशन: /etc/crontab, /etc/cron.d, /var/spool/cron/tabs. /bin/sh हा समान बॅश POSIX-अनुरूप नॉन-इंटरॅक्टिव्ह मोडमध्ये चालतो.

विक्सी क्रॉन डिव्हाइस

क्रॉनचे आधुनिक वंशज विक्सी क्रॉनच्या तुलनेत आमूलाग्र बदललेले नाहीत, परंतु तरीही त्यांनी नवीन वैशिष्ट्ये प्राप्त केली आहेत जी प्रोग्रामची तत्त्वे समजून घेण्यासाठी आवश्यक नाहीत. यापैकी बरेच विस्तार खराब डिझाइन केलेले आहेत आणि कोड गोंधळात टाकतात. पॉल विक्सीचा मूळ क्रॉन सोर्स कोड वाचून आनंद झाला.

म्हणून, मी विकासाच्या दोन्ही शाखांमध्ये सामान्य असलेल्या क्रॉन प्रोग्रामचे उदाहरण वापरून क्रॉन डिव्हाइसचे विश्लेषण करण्याचे ठरविले - Vixie cron 3.0pl1. वाचनात गुंतागुंत निर्माण करणारे ifdefs काढून टाकून आणि किरकोळ तपशील वगळून मी उदाहरणे सोपी करीन.

राक्षसाचे कार्य अनेक टप्प्यात विभागले जाऊ शकते:

  1. कार्यक्रम सुरू करत आहे.
  2. चालवण्‍याच्‍या कार्यांची सूची संकलित करणे आणि अपडेट करणे.
  3. मुख्य क्रॉन लूप चालू आहे.
  4. एखादे कार्य सुरू करा.

चला त्यांना क्रमाने पाहूया.

आरंभ

प्रारंभ केल्यावर, प्रक्रिया युक्तिवाद तपासल्यानंतर, क्रॉन SIGCHLD आणि SIGHUP सिग्नल हँडलर स्थापित करते. प्रथम एक लॉग एंट्री करते चाइल्ड प्रक्रियेच्या समाप्तीबद्दल, दुसरा लॉग फाइलचा फाइल वर्णनकर्ता बंद करतो:

signal(SIGCHLD, sigchld_handler);
signal(SIGHUP, sighup_handler);

क्रॉन डिमन नेहमी सिस्टीमवर एकटाच चालतो, फक्त सुपरयुजर म्हणून आणि मुख्य क्रॉन डिरेक्ट्रीमधून. खालील कॉल्स डिमन प्रक्रियेच्या पीआयडीसह एक लॉक फाइल तयार करतात, वापरकर्ता योग्य असल्याची खात्री करा आणि वर्तमान निर्देशिकेला मुख्यमध्ये बदला:

acquire_daemonlock(0);
set_cron_uid();
set_cron_cwd();

डीफॉल्ट मार्ग सेट केला आहे, जो प्रक्रिया सुरू करताना वापरला जाईल:

setenv("PATH", _PATH_DEFPATH, 1);

नंतर प्रक्रिया "डेमोनाइज्ड" केली जाते: ती फोर्क कॉल करून प्रक्रियेची चाइल्ड कॉपी तयार करते आणि चाइल्ड प्रक्रियेमध्ये नवीन सत्र (सेटसिड कॉल करणे) तयार करते. मूळ प्रक्रियेची यापुढे आवश्यकता नाही आणि ती बाहेर पडते:

switch (fork()) {
case -1:
    /* критическая ошибка и завершение работы */
    exit(0);
break;
case 0:
    /* дочерний процесс */
    (void) setsid();
break;
default:
    /* родительский процесс завершает работу */
    _exit(0);
}

पालक प्रक्रियेच्या समाप्तीमुळे लॉक फाइलवरील लॉक रिलीझ होतो. याव्यतिरिक्त, फाईलमधील पीआयडी मुलाला अद्यतनित करणे आवश्यक आहे. यानंतर, टास्क डेटाबेस भरला आहे:

/* повторный захват лока */
acquire_daemonlock(0);

/* Заполнение БД  */
database.head = NULL;
database.tail = NULL;
database.mtime = (time_t) 0;
load_database(&database);

मग क्रॉन मुख्य कार्य चक्राकडे जातो. परंतु त्याआधी, कार्य सूची लोड करण्यावर एक नजर टाकणे योग्य आहे.

कार्य सूची गोळा करणे आणि अद्यतनित करणे

load_database फंक्शन कार्यांची सूची लोड करण्यासाठी जबाबदार आहे. हे मुख्य सिस्टम क्रॉन्टॅब आणि वापरकर्ता फाइल्ससह निर्देशिका तपासते. फायली आणि निर्देशिका बदलल्या नसल्यास, कार्य सूची पुन्हा वाचली जात नाही. अन्यथा, कार्यांची नवीन यादी तयार होऊ लागते.

विशेष फाइल आणि सारणी नावांसह सिस्टम फाइल लोड करत आहे:

/* если файл системной таблицы изменился, перечитываем */
if (syscron_stat.st_mtime) {
    process_crontab("root", "*system*",
    SYSCRONTAB, &syscron_stat,
    &new_db, old_db);
}

लूपमध्ये वापरकर्ता सारण्या लोड करत आहे:

while (NULL != (dp = readdir(dir))) {
    char    fname[MAXNAMLEN+1],
            tabname[MAXNAMLEN+1];
    /* читать файлы с точкой не надо*/
    if (dp->d_name[0] == '.')
            continue;
    (void) strcpy(fname, dp->d_name);
    sprintf(tabname, CRON_TAB(fname));
    process_crontab(fname, fname, tabname,
                    &statbuf, &new_db, old_db);
}

त्यानंतर जुना डेटाबेस नवीनसह बदलला जातो.

वरील उदाहरणांमध्ये, process_crontab फंक्शन कॉल टेबल फाइल नावाशी जुळणारा वापरकर्ता अस्तित्वात असल्याची पडताळणी करतो (जोपर्यंत तो सुपरयुजर नसतो) आणि नंतर load_user ला कॉल करतो. नंतरचे आधीच ओळीनुसार फाइल स्वतः वाचते:

while ((status = load_env(envstr, file)) >= OK) {
    switch (status) {
    case ERR:
        free_user(u);
        u = NULL;
        goto done;
    case FALSE:
        e = load_entry(file, NULL, pw, envp);
        if (e) {
            e->next = u->crontab;
            u->crontab = e;
        }
        break;
    case TRUE:
        envp = env_set(envp, envstr);
        break;
    }
}

येथे, एकतर load_env / env_set फंक्शन्स वापरून पर्यावरण व्हेरिएबल सेट केले जाते (VAR=value च्या ओळी) किंवा load_entry फंक्शन वापरून टास्क वर्णन वाचले जाते (* * * * * /path/to/exec).

load_entry परत आणणारी एंट्री एंटिटी आमचे कार्य आहे, जे कार्यांच्या सामान्य सूचीमध्ये ठेवलेले आहे. फंक्शन स्वतःच वेळेच्या स्वरूपाचे वर्बोज पार्सिंग करते, परंतु आम्हाला पर्यावरण व्हेरिएबल्स आणि टास्क लॉन्च पॅरामीटर्स तयार करण्यात अधिक रस आहे:

/* пользователь и группа для запуска задачи берутся из passwd*/
e->uid = pw->pw_uid;
e->gid = pw->pw_gid;

/* шелл по умолчанию (/bin/sh), если пользователь не указал другое */
e->envp = env_copy(envp);
if (!env_get("SHELL", e->envp)) {
    sprintf(envstr, "SHELL=%s", _PATH_BSHELL);
    e->envp = env_set(e->envp, envstr);
}
/* домашняя директория */
if (!env_get("HOME", e->envp)) {
    sprintf(envstr, "HOME=%s", pw->pw_dir);
    e->envp = env_set(e->envp, envstr);
}
/* путь для поиска программ */
if (!env_get("PATH", e->envp)) {
    sprintf(envstr, "PATH=%s", _PATH_DEFPATH);
    e->envp = env_set(e->envp, envstr);
}
/* имя пользовтеля всегда из passwd */
sprintf(envstr, "%s=%s", "LOGNAME", pw->pw_name);
e->envp = env_set(e->envp, envstr);

मुख्य लूप कार्यांच्या वर्तमान सूचीसह कार्य करते.

मुख्य लूप

आवृत्ती 7 युनिक्समधील मूळ क्रॉनने अगदी सोप्या पद्धतीने काम केले: त्याने लूपमध्ये कॉन्फिगरेशन पुन्हा वाचले, सुपरयुझर म्हणून चालू मिनिटाची कार्ये सुरू केली आणि पुढच्या मिनिटाच्या सुरुवातीपर्यंत झोपली. जुन्या मशीनवरील या सोप्या पद्धतीसाठी खूप संसाधने आवश्यक आहेत.

SysV मध्ये एक पर्यायी आवृत्ती प्रस्तावित करण्यात आली होती, ज्यामध्ये डिमन एकतर जवळच्या मिनिटापर्यंत किंवा 30 मिनिटांसाठी झोपायला गेला. कॉन्फिगरेशन पुन्हा वाचण्यासाठी आणि या मोडमधील कार्ये तपासण्यासाठी कमी संसाधने वापरली गेली, परंतु कार्यांची सूची द्रुतपणे अद्यतनित करणे गैरसोयीचे झाले.

Vixie cron मिनिटातून एकदा कार्य सूची तपासण्यासाठी परत आला, सुदैवाने 80 च्या दशकाच्या अखेरीस मानक युनिक्स मशीनवर लक्षणीय संसाधने होती:

/* первичная загрузка задач */
load_database(&database);
/* запустить задачи, поставленные к выполнению после перезагрузки системы */
run_reboot_jobs(&database);
/* сделать TargetTime началом ближайшей минуты */
cron_sync();
while (TRUE) {
    /* выполнить задачи, после чего спать до TargetTime с поправкой на время, потраченное на задачи */
    cron_sleep();

    /* перечитать конфигурацию */
    load_database(&database);

    /* собрать задачи для данной минуты */
    cron_tick(&database);

    /* перевести TargetTime на начало следующей минуты */
    TargetTime += 60;
}

क्रॉन_स्लीप फंक्शन कार्ये कार्यान्वित करण्यात, job_runqueue (गणित करा आणि कार्ये चालवा) आणि do_command (प्रत्येक वैयक्तिक कार्य चालवा) फंक्शन्सना कॉल करण्यात थेट सहभागी आहे. शेवटचे कार्य अधिक तपशीलवार तपासण्यासारखे आहे.

एखादे कार्य चालवणे

do_command फंक्शन चांगल्या युनिक्स शैलीमध्ये कार्यान्वित केले जाते, म्हणजेच ते कार्य असिंक्रोनसपणे पार पाडण्यासाठी फोर्क करते. पालक प्रक्रिया कार्ये सुरू करणे सुरू ठेवते, मूल प्रक्रिया कार्य प्रक्रिया तयार करते:

switch (fork()) {
case -1:
    /*не смогли выполнить fork */
    break;
case 0:
    /* дочерний процесс: на всякий случай еще раз пробуем захватить главный лок */
    acquire_daemonlock(1);
    /* переходим к формированию процесса задачи */
    child_process(e, u);
    /* по завершению дочерний процесс заканчивает работу */
    _exit(OK_EXIT);
    break;
default:
    /* родительский процесс продолжает работу */
    break;
}

चाइल्ड_प्रोसेसमध्ये बरेच तर्कशास्त्र आहे: ते मानक आउटपुट आणि त्रुटी प्रवाह स्वीकारते, नंतर त्यांना मेलवर पाठवते (जर MAILTO पर्यावरण व्हेरिएबल टास्क टेबलमध्ये निर्दिष्ट केले असेल), आणि शेवटी, टास्कच्या मुख्य प्रक्रियेची प्रतीक्षा करते. पूर्ण

कार्य प्रक्रिया दुसर्या काट्याद्वारे तयार केली जाते:

switch (vfork()) {
case -1:
    /* при ошибки сразу завершается работа */
    exit(ERROR_EXIT);
case 0:
    /* процесс-внук формирует новую сессию, терминал и т.д.
     */
    (void) setsid();

    /*
     * дальше многословная настройка вывода процесса, опустим для краткости
     */

    /* смена директории, пользователя и группы пользователя,
     * то есть процесс больше не суперпользовательский
     */
    setgid(e->gid);
    setuid(e->uid);
    chdir(env_get("HOME", e->envp));

    /* запуск самой команды
     */
    {
        /* переменная окружения SHELL указывает на интерпретатор для запуска */
        char    *shell = env_get("SHELL", e->envp);

        /* процесс запускается без передачи окружения родительского процесса,
         * то есть именно так, как описано в таблице задач пользователя  */
        execle(shell, shell, "-c", e->cmd, (char *)0, e->envp);

        /* ошибка — и процесс на запустился? завершение работы */
        perror("execl");
        _exit(ERROR_EXIT);
    }
    break;
default:
    /* сам процесс продолжает работу: ждет завершения работы и вывода */
    break;
}

मुळात ते सर्व क्रॉन आहे. मी काही मनोरंजक तपशील वगळले, उदाहरणार्थ, रिमोट वापरकर्त्यांसाठी लेखांकन, परंतु मी मुख्य गोष्ट रेखांकित केली.

नंतरचा शब्द

क्रॉन हा एक आश्चर्यकारकपणे सोपा आणि उपयुक्त प्रोग्राम आहे, जो युनिक्स जगाच्या सर्वोत्तम परंपरांमध्ये बनविला गेला आहे. ती काही अतिरिक्त करत नाही, परंतु ती गेली अनेक दशके तिचे काम आश्चर्यकारकपणे करत आहे. उबंटूच्या आवृत्तीसाठी कोड मिळवण्यासाठी एका तासापेक्षा जास्त वेळ लागला नाही आणि मला खूप मजा आली! मला आशा आहे की मी ते तुमच्यासोबत शेअर करू शकलो.

मला तुमच्याबद्दल माहिती नाही, परंतु मला हे समजून थोडे वाईट वाटते की आधुनिक प्रोग्रामिंग, त्याच्या अति-जटिल आणि अति-अमूर्त प्रवृत्तीसह, बर्याच काळापासून अशा साधेपणासाठी अनुकूल नाही.

क्रॉनसाठी बरेच आधुनिक पर्याय आहेत: सिस्टमड-टाइमर तुम्हाला अवलंबित्वांसह जटिल प्रणाली आयोजित करण्यास परवानगी देते, fcron तुम्हाला कार्यांद्वारे संसाधन वापराचे अधिक लवचिकपणे नियमन करण्यास अनुमती देते. परंतु वैयक्तिकरित्या, सर्वात सोपा क्रॉन्टॅब माझ्यासाठी नेहमीच पुरेसा होता.

थोडक्यात, युनिक्सवर प्रेम करा, साधे प्रोग्राम वापरा आणि तुमच्या प्लॅटफॉर्मसाठी मन वाचायला विसरू नका!

स्त्रोत: www.habr.com

एक टिप्पणी जोडा