Bài viết này giới thiệu các bạn về cách quản lý cron trên hệ điều hành Linux.
1. Lệnh Cron
Cron là một tiến ích giúp chúng ta lập kế hoạch chạy những dòng lệnh trên server để thực hiện 1 hoặc nhiều công việc dựa trên thời gian được lập sẵn. Cron là một chương trình được chạy ngầm mãi một khi nó được khởi động lên.
Cron được điều khiển bởi một tệp cấu hình có tên /etc/crontab chứa các lệnh shell khác nhau cần được chạy vào thời gian được lên lịch chính xác.
Có tệp crontab trên toàn hệ thống và tệp crontab cho mỗi người dùng.
Mỗi dòng của tệp crontab đại diện cho một công việc và bao gồm một biểu thức được gọi là CRON , theo sau là một lệnh shell để thực thi.
Để mở trình soạn thảo crontab chỉnh sửa các công việc hoặc tạo công việc mới ta dùng lệnh:
crontab -e
Mỗi dòng của tệp crontab chứa 6 trường:
Định dạng của Crontab trên Linux:
MIN HOUR DOM MON DOW CMD
Bảng dưới đây sẽ thể hiện chức năng của định dạng trên:
Định dạng | Mô tả | Giá trị cho phép |
---|---|---|
MIN | Phút | 0 đến 59 |
HOUR | Giờ | 0 đến 23 |
DOM | Ngày trong tháng | 1 đến 31 |
MON | Tháng | 1 đến 12 |
DOW | Ngày trong tuần | 0 đến 6 |
CMD | Command | Lệnh cần thực thi |
2. Các ví dụ về cron
Ví dụ 1: Lên lịch cho một công việc trong một thời gian cụ thể
Sử dụng cron thực hiện chạy /home/ngocdang/backup.sh vào ngày 10 tháng 6 lúc 08:30
Lưu ý: Trường thời gian sử dụng định dạng 24 giờ. Vì vậy 8 giờ sáng sử dụng 8 giờ còn 8 giờ tối sử dụng 20 giờ.
30 08 10 06 * /home/ngocdang/backup.sh
Ví dụ trên thể hiện:
- 30 - 30 phút
- 08 - 08 giờ sáng
- 10 - Ngày 10
- 06 - Tháng 6
*
- Mỗi ngày trong tuần
Ví dụ 2. Lên lịch cho một công việc hai lần một ngày. Các tập lệnh sau đây sao lưu hai lần một ngày.
Sử dụng cron thực hiện chạy /home/ngocdang/backup.sh vào lúc 11:10 và 17:10 mỗi ngày. Giá trị được phân tách bằng dấu phẩy trong một trường.
10 11,17 * * * /home/ngocdang/backup.sh
Các trường ví dụ trên thể hiện:
- 10 - 10 phút
- 11,17 - 11 giờ sáng và 5 giờ chiều
*
- Mỗi ngày*
- Hàng tháng*
- Mỗi ngày trong tuần
Ví dụ 3. Sắp xếp công việc vào các ngày trong tuần
Nếu bạn muốn một công việc được thực hiện mỗi giờ trong một khoảng thời gian cụ thể thì hãy sử dụng như sau.
Ví dụ thực hiện chạy /home/ngocdang/script.sh hàng ngày trong khoảng thời gian từ 7 giờ sáng đến 6 giờ chiều
00 07-18 * * * /home/ngocdang/script.sh
Ý nghĩa các trường:
- 00 - 0 phút
- 07-18 - 7 giờ sáng, 8 giờ sáng, 9 giờ sáng, 10 giờ sáng, 11 giờ sáng, 12 giờ sáng, 1 giờ chiều, 2 giờ chiều, 3 giờ chiều, 4 giờ chiều, 5 giờ chiều, 6 giờ chiều
*
- Mỗi ngày*
- Hàng tháng*
- Mỗi ngày trong tuần
Ví dụ sau sẽ thực hiện chạy /home/ngocdang/backup.sh mỗi ngày trong tuần (không bao gồm thứ 7 và chủ nhật) trong giờ làm việc từ 9 giờ sáng đến 6 giờ chiều
00 09-18 * * 1-5 /home/ngocdang/backup.sh
Ý nghĩa các trường:
- 00 - 0 phút
- 09-18 - 9 giờ sáng, 10 giờ sáng, 11 giờ sáng, 12 giờ sáng, 1 giờ chiều, 2 giờ chiều, 3 giờ chiều, 4 giờ chiều, 5 giờ chiều, 6 giờ chiều
*
- Mỗi ngày*
- Hàng tháng- 1-5 - Mon, Tue, Wed, Thu và Fri
Ví dụ 4: Xem các mục Crontab
Xem các mục Crontab của người dùng đã đăng nhập hiện tại. Để xem các mục
crontab
chúng ta thực hiện lệnhcrontab -l
.[dang@test1 root]$ crontab -l 10 11,17 * * * /home/ngocdang/backup.sh 00 07-18 * * * /home/ngocdang/script.sh
Xem các mục Crontab của user root
Đăng nhập với tư cách người dùng root và thực hiện
crontab -l
[root@test1 ~]# crontab -l no crontab for root
Xem các mục Crontabs của người dùng Linux khác
Để xem các mục
crontab
của người dùng Linux khác, đăng nhập vào root và sử dụng cú pháp như sau:crontab -u {username} -l
[root@test1 ~]# crontab -u ngocdang -l 10 11,17 * * * /home/ngocdang/backup.sh 00 07-18 * * * /home/ngocdang/script.sh
Ví dụ 5: Chỉnh sửa mục Crontab
Chỉnh sửa các mục Crontab của người dùng hiện tại. Để chỉnh sửa các mục crontab
, sử dụng lệnh:
crontab -e
Crontab sẽ mở tệp crontab
trong trình chỉnh sửa Vim để chỉnh sửa. Để lưu tệp đã chỉnh sữa chúng ta dùng phím esc sau đó :wq và enter, nó sẽ lưu crontab
và hiển thị thông báo sau cho biết crontab
đã được sửa đổi thành công(crontab: installing new crontab)
Ví dụ 6: Lên lịch cho một công việc cho mỗi phút bằng Cron.
* * * * * command
Các trường *
có nghĩa là mỗi phút mỗi giờ trong suốt cả năm đều thực hiện command
đã yêu cầu.
3. Lệnh at, lệnh atp và lệnh atrm
3.1. Lệnh at
Lệnh at
thay thế cho bộ lập lịch cron
, cho phép chúng ta lên lịch một lệnh để chạy một lần tại một thời điểm nhất định mà không cần chỉnh sửa tệp cấu hình.
Để thực hiện lệnh at
chúng ta cần cài gói at
như sau:
Đối với Centos:
yum install at
Đối với Debian:
apt-get install at
Sau khi cài gói at
xong chúng ta khởi động như sau:
systemctl start atd
systemctl enable atd
Ví dụ 1: Khi muốn gửi 10 gói tin đến www.google.com vào 5 phút sau (ví dụ: nếu đó là 22:02:35, lệnh sẽ được thực thi lúc 22:07:35)
[root@test1 ~]# echo "ping -c 10 www.google.com" | at now + 5 minute
Ví dụ 2: Chạy updatedb
lúc 23 giờ hôm nay (hoặc ngày mai nếu giờ hiện tại lớn hơn 23 giờ) cú pháp như sau:
[root@test1 ~]# echo "updatedb" | at 23
Ví dụ 3: Tắt hệ thống lúc 23:55 hôm nay (hoặc ngày mai nếu giờ hiện tại lớn hơn 23:55) cách thực hiện như sau:
[root@test1 ~]# echo "shutdown -h now" | at 23:55
3.2 Lệnh atq
Lệnh atq
sẽ hiển thị tất cả các công việc đang chờ xử lý vẫn cần được thực thi..
Mỗi trường trong đầu ra atq
sẽ có:
- Số công việc
- Ngày mà công việc sẽ được thực hiện
- Giờ chính xác khi số công việc sẽ được thực thi
- Tên của hàng đợi
- Tên người dùng đã lên lịch cho công việc
Ví dụ 1: Chúng ta lên lịch cho một công việc sẽ thực thi gửi 10 gói tin đến www.google.com vào 5 phút sau.
[root@test1 ~]# echo "ping -c 10 www.google.com" | at now + 5 minute
job 8 at Tue Mar 12 23:01:00 2019
Khi chúng ta thực thi lệnh at
, sau đó dùng lệnh atq
hiển thị tất cả các công việc đang chờ xử lý như dưới đây.
[root@test1 ~]# atq
8 Tue Mar 12 23:01:00 2019 a root
Ví dụ 2: Hiển thị công việc hàng đợi có tên là 'a' thực hiện như sau:
atq -q a
Ví dụ 3: Để xem list các công việc được lên lịch thực hiện như sau:
at -c jobnumber
Đối với cú pháp trên chúng ta chỉ xem được 1 công việc duy nhất. Để xem tất cả các công việc chúng ta sẽ thực hiện lệnh như sau:
for j in $(atq | cut -f 1); do at -c "$j"; done
3.3 Lệnh atrm
Lệnh atrm
dùng loại bỏ các công việc đã được lên lịch. Chúng ta có thể xem ID công việc bằng cách thực hiện lệnh atq
Ví dụ 1: Xóa công việc số 10 chúng ta thực hiện như sau
atrm 10
Ví dụ 2: Xóa nhiều công việc, thì các công việc cách nhau bởi khoảng trắng
atrm 1 5 7 12
4. Systemd timer
Systemd timer là giải pháp có thể thay thế cron hoàn toàn trên các hệ thống có dùng systemd.
4.1. Liệt kê các bộ đếm thời gian hiện có
Chúng ta sử dụng cú pháp kiểm tra xem bộ đếm thời gian tồn tại trên máy tính như sau:
systemctl list-timers
Sử dụng tùy chọn --all
sẽ cho thấy cả giờ không hoạt động.
systemctl list-timers --all
Chúng ta có thể xem ngày và giờ mỗi bộ hẹn giờ sẽ kích hoạt, đếm ngược cho đến thời điểm đó, thời gian đã trôi qua kể từ lần chạy cuối cùng, tên đơn vị của bộ hẹn giờ và dịch vụ mỗi đơn vị hẹn giờ kích hoạt. Tất cả các bộ định thời phải được ghép nối với một dịch vụ tương ứng.
4.2. Tạo dịch vụ
Chúng ta muốn chạy một lệnh sao lưu cho một trang web của chúng ta mỗi ngày.
Tạo thư mục /var/www/backupweb:
[root@test1 ~]# /var/www/backupweb
Tạo tệp /var/www/backupweb/backup.sh và dán các dòng sau:
#!/bin/bash
DAYMONTH=`date "+%d"`
/bin/tar --selinux -czvf /var/www/backup/backup-$DAYMONTH.tgz /var/www/html &>/dev/null
Cung cấp cho tệp mới tạo quyền thực thi:
[root@test1 ~]# chmod +x /var/www/backupweb/backup.sh
Tạo tệp /usr/lib/systemd/system/backup.service và dán các dòng sau:
[Unit]
Description=Backup of my apache website
[Service]
Type=simple
ExecStart=/var/www/backup/backup.sh
[Install]
WantedBy=multi-user.target
4.3. Tạo hẹn giờ
Cú pháp cơ bản tạo hẹn thời gian như sau:
[Unit]
Description=Execute backup every day at midnight
[Timer]
OnCalendar=*-*-* 11:43:00
Persistent=true
[Install]
WantedBy=timers.target
Trong đó gồm 3 phần:
- Phần Unit Tùy chọn Description (mô tả tên nội dung trong tệp hoặc mô tả của bộ định thời gian). Bạn có thể thay đổi cách mô tả về theo ý thích của bạn.
Phần Timer
*-*-*l
là viết tắt của Năm-Tháng-Ngày, và các dấu hoa thị có nghĩa là nó sẽ chạy mỗi ngày mỗi tháng mỗi năm từ lúc bộ định thơi gian khời động. Thời gian theo dấu hoa thị cho thấy thời gian nào trong ngày hẹn giờ chạy.Persistent=true
có nghĩa là bộ đếm thời gian sẽ tự động chạy nếu nó bỏ lỡ thời gian bắt đầu trước đó. Điều này có thể xảy ra vì máy tính đã bị tắt trước khi sự kiện có thể diễn ra. Đây là tùy chọn nên nhớ.Phần Install
WantedBy=timers.target
cho thấy Systemd timers.target sẽ sử dụng tệp .timer. Dòng này trong tệp hiển thị chuỗi phụ thuộc từ tệp này sang tệp khác. Bạn không nên bỏ qua hoặc thay đổi dòng này.
Ví dụ: Tạo tệp /usr/lib/systemd/system/backup.timer và dán các dòng sau:
[Unit]
Description=Execute backup every day at midnight
[Timer]
OnCalendar=*-*-* 00:00:00
Unit=backup.service
[Install]
WantedBy=timers.target
Một số tùy chọn khác như OnCallendar có sẵn:
- OnActiveSec: bộ định thời gian liên quan đến thời điểm bộ định thời gian được kích hoạt.
- OnBootSec: bộ hẹn giờ liên quan đến thời điểm máy được khởi động.
- OnStartupSec: một bộ định thời gian liên quan đến thời điểm systemd được khởi động.
- OnUnitActiveSec: một bộ định thời gian liên quan đến thời điểm đơn vị mà bộ định thời kích hoạt được kích hoạt lần cuối.
- OnUnitInactiveSec: bộ định thời liên quan đến thời điểm thiết bị hẹn giờ được kích hoạt lần cuối bị hủy kích hoạt.
Bản phát hành RHEL 7.2 mang đến ba tùy chọn mới:
- AccuracySec: xác định cửa sổ thời gian trong bộ đếm thời gian được lên lịch để trôi qua (1 phút theo mặc định).
- Persistent, a boolean, nếu được đặt thành true: thời điểm đơn vị dịch vụ được kích hoạt lần cuối được lưu trữ trên đĩa. Thông tin này sau đó được sử dụng trong lần khởi động lại tiếp theo để có thể thực hiện các sự kiện hẹn giờ quá hạn.
- WakeSystem, a boolean, nếu được đặt thành true: bộ định thời gian được cấu hình theo cách này sẽ khiến hệ thống tiếp tục từ hệ thống treo.
4.5. Cú pháp date
Mỗi tùy chọn trước đó sử dụng cú pháp ngày bên dưới:
Dang tối thiểu Dạng chuẩn hoá
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
2003-03-05 ==> 2003-03-05 00:00:00
03-05 ==> *-03-05 00:00:00
hourly ==> *-*-* *:00:00
daily ==> *-*-* 00:00:00
monthly ==> *-*-01 00:00:00
weekly ==> Mon *-*-* 00:00:00
*:20/15 ==> *-*-* *:20/15:00
Lưu ý: *:20/15 có nghĩa là *:20:00, *:35:00, *:50:00 và khởi động lại lúc *:20:00 tiếp theo.
4.4. Cách kích hoạt, kiểm tra, tải lại bộ định thời gian
Kích hoạt khi khởi động và bắt đầu hẹn giờ sao lưu để sao lưu trang web của bạn mỗi ngày:
systemctl enable backup.timer
systemctl start backup.timer
Để kiểm tra xem bộ hẹn giờ sao lưu có được bật hay không
systemctl is-enable backup.timer
Để kiểm tra xem bộ đếm thời gian sao lưu có đang chạy hay không
systemctl is-active backup.timer
Muốn chạy tập lệnh sao lưu bất cứ lúc nào
systemctl start backup
Khi chúng ta thay đổi tần suất sao lưu, sau khi sửa đổi giá trị OnCalendar chúng ta phải thực hiện như sau:
systemctl daemon-reload
5. File /etc/crontab
Tệp crontab
của Linux (/etc/crontab) được xác định theo một định dạng cụ thể. Mỗi dòng có thể để trống, một nhận xét được bắt đầu bằng #, một biến hoặc một lệnh. Các dòng trống trong tệp crontab
(/etc/crontab) trên hệ điều hành Linux sẽ được bỏ qua.
Cron được điều khiển bởi một tập hợp các tệp gọi là crontabs
. Tệp chính là /etc/crontab. Các tập tin crontab cho người dùng được đặt trong /var/spool/cron/. Trong /var/spool/cron, các tệp được đặt cùng tên với ID đăng nhập của người dùng.
Tệp crontab (/etc/crontab) sẽ tự động thực thi các mục trong một số thư mục con trong các khoảng thời gian thông thường.
6. File /etc/at.allow và file /etc/at.deny
Chúng ta có thể hạn chế quyền truy cập vào at
bằng cách sử dụng file /etc/at.allow và file /etc/at.deny. Các tệp kiểm soát truy cập này sử dụng cùng định dạng xác định một tên người dùng trên mỗi dòng.
Lưu ý: Không có khoảng trắng nào được cho phép trong hai tệp.
Có 2 trường hợp như sau:
- Nếu tệp /etc/at.allow tồn tại, chỉ những người dùng được liệt kê trong tệp mới được phép sử dụng lệnh
at
và tệp /etc/at.deny bị bỏ qua. - Nếu tệp /etc/at.allow không tồn tại, người dùng được liệt kê trong tệp /etc/at.deny không được phép sử dụng lệnh
at
.
Người dùng root luôn có thể thực thi lệnh at
, bất kể nội dung bên trong của tệp kiểm soát truy cập.
7. File /etc/cron.allow và file /etc/cron.deny
Chúng ta có thể kiểm soát quyền truy cập crontab
bằng cách sử dụng hai file /etc/cron.deny và file /etc/cron.allow. Các tệp này chỉ cho phép người dùng được chỉ định thực hiện crontab
các tác vụ như tạo, chỉnh sửa, hiển thị hoặc xóa các crontab
của riêng họ .
Các file /etc/cron.deny và file/etc/cron.allow bao gồm một danh sách các tên người dùng, mỗi tên một dòng.
Các tệp kiểm soát truy cập này hoạt động cùng nhau như sau:
- Nếu file /etc/cron.allow tồn tại, chỉ những người dùng được liệt kê trong tệp này mới có thể tạo, chỉnh sửa, hiển thị hoặc xóa
crontab
. - Nếu file /etc/cron.allow không tồn tại, tất cả người dùng có thể gửi tệp
crontab
, ngoại trừ người dùng được liệt kê trong file /etc/cron.deny. - Nếu không có file /etc/cron.allow cũng không có file /etc/cron.deny tồn tại, đặc quyền superuser(root) sẽ cần thiết để chạy
crontab
. Đặc quyền Superuser(root) được yêu cầu để chỉnh sửa hoặc tạo file /etc/cron.deny và file /etc/cron.allow.