قبلا از خواندن لطفا توجه بفرمایید:
تایمر فایلها = Timer files
سرویس فایلها = Service files
تارگت فایلها = Target files
------------------------------------------------------------------------------------------------------------------------
فکر میکنم نیاز به توضیح اضافهای نباشه درمورد اینکه cron چی هست و چه کاربردی داره چون همهی دوستان به این مساله واقف هستند. پس بی مقدمه میریم سر اصل مطلب. توی این آموزش تصمیم داریم از systemd/Timers به جای cron استفاده کنیم. برای این هدف ما به چند فایل نیازمند هستیم که دو تا از این فایلها تایمر فایلها و سرویس فایلها هستند.
تایمر فایلها:
این فایلها در اقع همان کار زمانبندی را انجام میدهند و با پسوند timer. نمایش داده میشوند و وظیفهی کنترل سرویس فایلها رو به عهده دارند. این فایلها از دو نوع شیوهی زمان دهی پشتیبانی میکنند. یکی realtime که زمان تقویمی هست و با تاریخ تقویم فعال میشوند و یکی Monotonic که فعال شدن تایمر رو به یک نقطهی زمانی وابسته میکنند(بعدا با یک مثال متوجه خواهیم شد).تایمر فایلها معمولا از دوبخش [Unit] و [Timer] تشکیل شده اند. که زمان دهی در قسمت [Timer] انجام میشود.ساختار تایمرفایلها شبیه ساختار زیر است
[Unit]
Description=Something about file or action
[Timer]
OnCalendar=date or time
OnBootSec=time after boot
[Install]
WantedBy=multi-uer.target
تایمر فایلها به طور خودکار از وابستگیهای پیش فرض بهره میبرند مگر اینکه در ساختار آنها در بخش [Unit] برای =DeafaultDependencies مقدار false در نظر گرفته شود. مثلا زمان خاموشی سیستم برای متوقف شدن کامل و درست از shutdown.target پیروی میکنند.(درمورد تارگتها بعدا یه توضیح میدم
)
اما برای زمان دهی به تایمر فایلها دو گزینه پیش روی ما بود یا فعالیت تایمر بر اساس تاریخ تقویم یا تخصیص نقطهای برای فعال شدن. برای تخصیص زمان تقویمی باید از آپشن OnCalendar در بخش [Unit] استفاده کنیم. مثلا فلان تایمر دوشنبهها ساعت ۱۲:۰۰:۰۰ استارت بشه. تاریخها را به شکلهای متفاوتی میتوانیم تعریف کنیم که چند نمونه از آن ذکر شده ولی قبل از ذکر نمونه باید با شکل کلی آن آشنا شویم:
OnCalendar=*-*-* *:*:*
سه * اول مربوط به تاریخ روز و ماه و سال و سه * بعد مربوط به ساعت دقیقه و ثانیه. مثلا:
OnCalendar=2016-06-16 23:45:30
اما این امکان وجود داره که ما تایمر رو به شکل دورهای فعال کنیم مثلا روزانه، هفتگی، ماهیانه، سالیانه که در این صورت برای راحتی استفاده از این گزینهها امکان پذیر است:
minutely, hourly, daily, monthly, weekly, yearly
تصمیم داریم که تایمری را هر ۱۵ دقیقه یکبار فعال کنیم:
OnCalendar=*:0/15
شکلهای دیگر:
Sat,Thu,Mon-Wed,Sat-Sun → Mon-Thu,Sat,Sun *-*-* 00:00:00
Mon,Sun 12-*-* 2,1:23 → Mon,Sun 2012-*-* 01,02:23:00
Wed *-1 → Wed *-*-01 00:00:00
Wed-Wed,Wed *-1 → Wed *-*-01 00:00:00
Wed, 17:48 → Wed *-*-* 17:48:00
Wed-Sat,Tue 12-10-15 1:2:3 → Tue-Sat 2012-10-15 01:02:03
*-*-7 0:0:0 → *-*-07 00:00:00
10-15 → *-10-15 00:00:00
monday *-12-* 17:00 → Mon *-12-* 17:00:00
Mon,Fri *-*-3,1,2 *:30:45 → Mon,Fri *-*-01,02,03 *:30:45
12,14,13,12:20,10,30 → *-*-* 12,13,14:10,20,30:00
mon,fri *-1/2-1,3 *:30:45 → Mon,Fri *-01/2-01,03 *:30:45
03-05 08:05:40 → *-03-05 08:05:40
08:05:40 → *-*-* 08:05:40
05:40 → *-*-* 05:40:00
Sat,Sun 12-05 08:05:40 → Sat,Sun *-12-05 08:05:40
Sat,Sun 08:05:40 → Sat,Sun *-*-* 08:05:40
2003-03-05 05:40 → 2003-03-05 05:40:00
05:40:23.4200004/3.1700005 → 05:40:23.420000/3.170001
2003-03-05 05:40 UTC → 2003-03-05 05:40:00 UTC
2003-03-05 → 2003-03-05 00:00:00
03-05 → *-03-05 00:00:00
hourly → *-*-* *:00:00
daily → *-*-* 00:00:00
daily UTC → *-*-* 00:00:00 UTC
monthly → *-*-01 00:00:00
weekly → Mon *-*-* 00:00:00
yearly → *-01-01 00:00:00
annually → *-01-01 00:00:00
*:2/3 → *-*-* *:02/3:00
اما در مورد شکل دوم زماندهی به تایمر. در این شکل ما با آپشنهای
OnActiveSec=, OnBootSec=, OnStartupSec=, OnUnitActiveSec=, OnUnitInactiveSec=
سر و کار داریم.
=OnActiveSec فعالیت را به زمانی که خود تایمر فعال شده است وابسته میکند. مثلا یک سرویس یک دقیقه بعد از فعال شدن تایمر فعال شود.
=OnBootSec وابسته به زمانی که سیستم بوت میشود.
=OnStartupSec زمانی که سیستم استارت میشود.
=OnUnitActiveSec تایمری را تعریف میکند که به زمانی که تایمر آخرین بار فعال بوده است وابسته میکند.(زمان آغاز آخرین فعالیت تایمر)
=OnUnitInactiveSec تایمری را تعریف میکند که به زمانی که تایمر آخرین بار غیر فعال شده است وابسته میکند (زمان پایان آخرین فعالیت تایمر)
برای مثال میخواهیم تایمری تعریف کنیم که یک دقیقه بعد از بوت شدن فعال شود و هر ده دقیقه بعد از شروع آخرین فعالیت دوباره فعال شود:
[Unit]
Descrition=active every 10 miniutes
[Timer]
OnBootSec=1min
OnUnitActiveSec=10min
و به این شکل تایمر ما هر ده دقیقه اجرا میشود.
اما اینها همه برای ساختن تایمر فایل بود. در اقع ما برای اجرای یک سرویس تایمری را پیکربندی میکنیم. پس باید یک سرویس در کنار تایمر ما تعریف شود. این سرویس نیز مثل تایمر فایلها ساختاری دارند.ساختار سرویس فایلها هم به شکل زیر است:
[Unit]
Description=Something about service
[Service]
ExecStart=Command or Path to script
Type=simple
داخل این ساختار جای پیچیده و گنگی نیست. دستوری که قرار است اجرا شود باید در جلوی =ExecStart قرار بگیرد یا مسیری که اسکریپت در آنجا قرار گرفته است.
مقدار Type هم simple باشد تا سرویس ما قابلیت فعال شدن دوباره را داشته باشد. مقادیری مانند oneshot، notify و ... هم وجود دارد که هر کدام برای یک سری از اهداف کاربرد دارد. مثلا oneshot موجب میشود که سرویس یک بار اجرا شود و دیگر اجرا نشود.
نکته: برای هر تایمر فایل یک سرویس فایل همنام خودش وجود دارد. مثلا Example.timer و Example.service و اگر در تایمر فایل تعیین نشود که کدام سرویس فعال شود سعی میکند که سرویسی همنام خودش را اجرا کند. مسیر هر دوی تایمر فایلها و سرویسها یکسان است. برای توزیع من (آرچ) این مسیر است:
/etc/systemd/system/
یک مثال واقعیتر:
#!/bin/bash
`echo $(date) >> "/home/farid/Desktop/date"`
این محتوای اسکریپتی است با نام Test.sh که در دسکتاپ قرار گرفته و خروجی آن تاریخ فعلی است که در فایل date روی دسکتاپ ذخیره میشود.
اکنون ما باید دو فایل timer. و service. را ساخته و پیکربندی کنیم.
sudo vim /etc/systemd/system/Test.service
[Unite]
Description=My first service
[Service]
Type=simple
ExecStart=/home/farid/Desktop/Test.sh
sudo vim /etc/systemd/system/Test.timer
[Unit]
Description=My first timer
[Timer]
OnCalendar=*:0/15
Unite=Test.service
[Install]
WantedBy=multi-user.target
بعد از ساختن فایلها کافیست که تایمر و سرویس را enable کنیم.
sudo systemctl enable Test.service
sudo systemctl enable Test.timer
sudo systemctl start Test.timer
اما target. فایلها چیستند؟ فرض کنیم میخواهیم در یک زمان یکسان درواقع با یک تایمرفایل چند سرویس را اجرا کنیم. برای این منظور نیاز به تارگت فایلها داریم که با پسوند target. نمایش داده میشوند. ساختار تارگت فایلها هم شبیه زیر است:
[Unit]
Description=Something about what your heart want
البته در بخش [Unit] این فایلها میتوان تنظیمات بسیار پیشرفتهتری نیز اعمال کرد. تارگت فایلها وظیفهی گروهبندی سرویسها را دارند.
و در همان مسیر تایمر فایلها و سرویس فایلها ساخته و قرار داده میشوند. در مثال قبل فرض میکنیم که ما علاوه بر Test.service سرویس دیگری با نام Test2.service داریم و این دو سرویس باید همزمان بر اساس تایمر فایل اجرا شوند. پس کافیست تارگت فایل را بسازیم و در انتهای سرویس فایلهایمان مقدار زیر را وارد کنیم (اگر نام تارگت فایل ما Test.target باشد):
[Install]
WantedBy=Test.target
Test.service content
[Unite]
Description=My first service
[Service]
Type=simple
ExecStart=/home/farid/Desktop/Test.sh
[Install]
WantedBy=Test.target
سپس مقدار Unit در Test.timer را به Test.target تغییر بدهیم.
Test.timer content
[Unit]
Description=My first timer
[Timer]
OnCalendar=*:0/15
Unite=Test.target
[Install]
WantedBy=multi-user.target
باید بعد از هر تغییر در سرویسها یا تایمر قبل از استارت کردن یا enable کردن آنها دستور زیر را اجرا کنیم:
sudo systemctl daemon-reload
کافیست که سرویسها و تایمر را دوباره راه اندازی و enable کنیم.
نکته: برای ایجاد دقت در شمارندهی تایمر و سیستم میتوانیم از =AccuracySec در تایمر در بخش [Timer] استفاده کنیم. بهتر است مقدار را برابر با 1us قرار دهیم.AccuracySec=1us
قطعا این آموزش خالی از اشتباه نیست. خواهش میکنم برای تصحیح، اشتباهات را تذکر بفرمایید. با تشکر