Chương 10 — Automation & cron
Chương cuối — nơi mọi thứ bạn học được biến thành tự động. Không còn ngồi gõ lại cùng một lệnh mỗi sáng. Máy tính sẽ tự backup, tự dọn rác, tự kiểm tra ổ cứng — bạn chỉ cần mở Terminal để xem báo cáo. Đi nốt 10 section này và bạn đã đi trọn 10 chương CLI Mastery.
1. Tự động hoá là gì
Tự động hoá CLI có một công thức đơn giản: "việc lặp đi lặp lại → script → schedule". Mỗi khi bạn nhận ra mình gõ cùng một chuỗi lệnh nhiều hơn 2 lần, đó là tín hiệu nên đóng gói nó thành script; và nếu việc đó cần chạy theo lịch, ta giao cho một scheduler như cron / launchd / systemd lo phần đúng giờ.
Ba ví dụ kinh điển
- Backup hằng đêm — mỗi 2h sáng đóng gói
~/Documentsthành.tar.gztrong~/backup/. - Dọn temp file cuối tuần — chủ nhật 3h sáng xoá mọi file trong
~/Downloadscũ hơn 30 ngày. - Kiểm tra disk usage — mỗi giờ chạy
df -h, nếu phân vùng/> 80% thì gửi notification.
# Pipeline tự động hoá điển hình
việc lặp lại → viết script .sh → chmod +x → test thủ công → schedule (cron/launchd) → log + alert
2. cron — scheduler kinh điển
cron là daemon chạy nền trên Unix từ thập niên 70. Mỗi user có một crontab riêng — danh sách các job theo lịch.
Sửa nó bằng crontab -e, xem nó bằng crontab -l, xoá sạch bằng crontab -r.
$ crontab -e # mở editor để sửa job
$ crontab -l # list các job hiện có
$ crontab -r # xoá toàn bộ — cẩn thận!
Format 5 cột
* * * * * command-to-run
│ │ │ │ │
│ │ │ │ └── day of week (0-6, 0 = Chủ nhật)
│ │ │ └───── month (1-12)
│ │ └──────── day of month (1-31)
│ └─────────── hour (0-23)
└────────────── minute (0-59)
Pattern phổ biến
| Cron expression | Ý nghĩa |
|---|---|
* * * * * | Mỗi phút |
*/5 * * * * | Mỗi 5 phút |
0 * * * * | Đầu mỗi giờ (xx:00) |
0 2 * * * | Mỗi đêm 2h sáng |
0 9 * * 1 | Mỗi thứ Hai 9h sáng |
30 3 1 * * | Ngày 1 hàng tháng, 3h30 sáng |
0 0 * * 0 | Mỗi Chủ nhật nửa đêm |
# Ví dụ một dòng trong crontab
0 2 * * * /Users/you/bin/backup.sh >> /Users/you/logs/backup.log 2>&1
$PATH như shell tương tác. Lệnh node, brew, python3
rất dễ "không tìm thấy". Luôn dùng absolute path (vd /opt/homebrew/bin/node) hoặc set PATH=... ở đầu crontab.
3. launchd trên macOS
Apple khuyến nghị dùng launchd thay cho cron trên macOS. cron vẫn chạy được nhưng đã deprecated từ lâu.
launchd quản lý cả daemon hệ thống lẫn job theo lịch của user — mỗi job là một file .plist (XML).
| Vị trí | Dùng cho |
|---|---|
~/Library/LaunchAgents/ | Job của user, chạy khi bạn login |
/Library/LaunchAgents/ | Job cho mọi user |
/Library/LaunchDaemons/ | Daemon hệ thống, chạy ngay cả khi chưa login |
Plist tối thiểu — chạy script mỗi giờ
# File: ~/Library/LaunchAgents/com.you.hourly.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.you.hourly</string>
<key>ProgramArguments</key>
<array>
<string>/Users/you/bin/hourly.sh</string>
</array>
<key>StartInterval</key>
<integer>3600</integer> <!-- 3600s = 1h -->
<key>StandardOutPath</key>
<string>/Users/you/logs/hourly.log</string>
<key>StandardErrorPath</key>
<string>/Users/you/logs/hourly.err</string>
</dict>
</plist>
Quản lý job
$ launchctl load ~/Library/LaunchAgents/com.you.hourly.plist
$ launchctl list | grep com.you
$ launchctl unload ~/Library/LaunchAgents/com.you.hourly.plist
$ launchctl start com.you.hourly # chạy ngay 1 lần để test
Mẹo: dùng StartCalendarInterval thay StartInterval để lên lịch theo giờ tuyệt đối (vd "mỗi đêm 2h"),
giống cột giờ/phút của cron nhưng viết bằng XML.
4. systemd timer (Linux)
Đa số distro Linux hiện đại (Ubuntu, Debian, Fedora, Arch) dùng systemd. Thay vì cron, người ta dùng cặp file
.service + .timer đặt trong /etc/systemd/system/. Bạn ít chạm trên macOS, nhưng khi SSH
vào server Linux thì gần như chắc chắn gặp.
# /etc/systemd/system/backup.service
[Unit]
Description=Daily backup job
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
# /etc/systemd/system/backup.timer
[Unit]
Description=Run backup every day at 02:00
[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true
[Install]
WantedBy=timers.target
$ sudo systemctl enable --now backup.timer
$ systemctl list-timers # xem mọi timer + thời gian chạy kế
$ journalctl -u backup.service # xem log của job
cron vs launchd vs systemd
| Đặc điểm | cron | launchd (macOS) | systemd (Linux) |
|---|---|---|---|
| Format | 1 dòng / job | XML plist | 2 file INI |
| Logging | Phải tự redirect | StandardOutPath | journalctl tích hợp |
| Khởi động khi miss lịch | Không | Có (RunAtLoad) | Có (Persistent=true) |
| Nền tảng | Mọi Unix | Chỉ macOS | Đa số Linux modern |
| Độ phức tạp | Rất đơn giản | Trung bình (XML dài dòng) | Trung bình |
5. Logging & log rotation
Script tự động chạy nền — bạn không thấy output trên Terminal. Nếu không log lại, một ngày nó chết âm thầm và bạn không hề hay biết. Quy tắc: luôn redirect cả stdout và stderr ra file log có dấu thời gian.
# Trong script, hoặc ngay trong dòng cron:
$ ./backup.sh >> ~/logs/backup-$(date +%F).log 2>&1
# ^ stderr về cùng file stdout
Log file dồn lâu ngày sẽ ăn hết ổ cứng. Cần log rotation:
| Hệ điều hành | Tool rotate | Config ở đâu |
|---|---|---|
| Linux | logrotate | /etc/logrotate.d/yourapp |
| macOS | newsyslog | /etc/newsyslog.d/yourapp.conf |
# Ví dụ logrotate config — giữ 7 ngày, nén lại
/Users/you/logs/*.log {
daily
rotate 7
compress
missingok
notifempty
}
Nguyên tắc thực tế: log mỗi ngày 1 file, giữ 1-2 tuần, file cũ nén .gz. Quá đó thì xoá — bạn sẽ không bao giờ đọc log từ tháng trước.
6. Monitor & alert
Tự động hoá cao cấp = không chỉ chạy mà còn báo cho bạn biết khi có vấn đề. Kết hợp cron + curl
+ jq (Chương 8) + một kênh notification → bạn có một dashboard mini cho riêng mình.
Notification trên macOS
$ osascript -e 'display notification "Disk > 80%" with title "Cảnh báo"'
Slack webhook (nếu bạn xài Slack)
$ curl -X POST -H 'Content-Type: application/json' \
-d '{"text":"Backup FAILED on $(hostname)"}' \
https://hooks.slack.com/services/XXX/YYY/ZZZ
Health check + alert — script mẫu
#!/bin/bash
# check-disk.sh — cảnh báo nếu / vượt 80%
USAGE=$(df -h / | awk 'NR==2 {print $5}' | tr -d '%')
if [ "$USAGE" -gt 80 ]; then
osascript -e "display notification \"Disk = ${USAGE}%\" with title \"Cảnh báo CLI\""
echo "[$(date)] WARN: disk = ${USAGE}%" >> ~/logs/disk.log
fi
Check một API
$ curl -s https://api.example.com/health \
| jq -r .status \
| grep -q ok || osascript -e 'display notification "API down!" with title "ALERT"'
Đem 3 script trên + cron là bạn đã có một hệ thống monitor cá nhân. Không xịn bằng Datadog nhưng đủ để máy bạn không bao giờ bị "đầy ổ" giữa lúc deadline.
7. Thử ngay trong terminal giả lập
Simulator hỗ trợ vài lệnh demo của chương — thử chuỗi sau:
- Xem crontab hiện tại:
crontab -l - Liệt kê job launchd của bạn:
launchctl list - Xem lịch tiếp theo của các timer:
systemctl list-timers - Tạo folder chứa log:
mkdir -p ~/logs - Test redirect:
date >> ~/logs/test.log 2>&1 - Đọc log:
cat ~/logs/test.log
8. Bài tập về nhà
Trên Terminal thật — đây là chương cuối nên hãy làm ít nhất 6/9 bài:
- Tạo script
~/bin/backup.shđóng gói~/Documentsra~/backup/$(date +%F).tar.gz.chmod +xrồi chạy thử. - Thêm dòng cron chạy
backup.shmỗi giờ. Dùng crontab.guru xác nhận expression đúng. - Đảm bảo log của job ghi ra
~/logs/backup.logvới cả stderr (2>&1). - Viết file
~/Library/LaunchAgents/com.you.nightly.plistchạybackup.shmỗi đêm 2h sáng. Load + test bằnglaunchctl start. - Viết script
check-disk.sh: nếu phân vùng/> 80%, gửi notification bằngosascript. Schedule mỗi giờ. - Viết script
cleanup-downloads.shxoá file trong~/Downloadscũ hơn 30 ngày (find ~/Downloads -mtime +30 -delete). Schedule mỗi Chủ nhật 3h sáng. - Trong cron có một job dùng
node script.jsnhưng báo lỗi "node: command not found". Tìm absolute path của node (which node) và sửa lại. Vì sao lỗi xảy ra? - Đặt config
logrotate(Linux) hoặcnewsyslog(macOS) cho thư mục~/logsgiữ 7 ngày, nén file cũ. - Bonus capstone: kết hợp mọi thứ đã học — viết một script theo dõi 3 thứ (disk, RAM bằng
vm_stat, một API tuỳ chọn) rồi gửi notification khi có vấn đề. Schedule mỗi 15 phút.
9. Quiz — Kiểm tra kiến thức
10. Tổng kết khoá học 🎉
Bạn vừa đi xong 10 chương CLI Mastery. Hãy nhìn lại — bạn đã đi xa đến đâu rồi:
- ✅ Chương 1 — Navigation:
cd,ls,pwdtrong giấc ngủ - ✅ Chương 2 — File operations & permissions:
chmod 755không còn ma thuật - ✅ Chương 3 — Pipes & redirects: ghép lệnh thành dây chuyền xử lý
- ✅ Chương 4 — Text processing:
grep,sed,awk,cut - ✅ Chương 5 — Process management:
ps,kill, jobs nền - ✅ Chương 6 — Networking:
curl,ssh,nc, port - ✅ Chương 7 — Shell scripting: biến, if, for, function
- ✅ Chương 8 — JSON & data wrangling:
jqnhư dao Thuỵ Sĩ - ✅ Chương 9 — Git & tooling: branch, rebase, đời sống dev thật
- ✅ Chương 10 — Automation: cron, launchd, monitor
Bạn không còn là beginner. Bạn có thể mở Terminal trên bất kỳ Mac/Linux nào và làm việc ở đó — không cần GUI. Với người chưa biết CLI, đây là một siêu năng lực thật sự: tự động hoá những việc người khác phải làm thủ công mỗi ngày.
Bước kế tiếp — sau khoá học
- Viết cheatsheet riêng — tổng hợp các lệnh bạn dùng nhiều nhất từ 10 chương vào một file
cheatsheet.mdtrong~/notes. - Đóng góp dotfiles — push
~/.zshrc, alias, function của bạn lên một repo Git công khai. Đây là portfolio của dev. - Học Vim/Neovim — editor sống trong Terminal. Bắt đầu bằng
vimtutor, kiên trì 2 tuần là dùng được thật. - Học Docker CLI — bước tự nhiên tiếp theo: đóng gói app, chạy container.
docker run,docker compose. - Build script hằng ngày — mỗi tuần thêm 1 script vào
~/bin. Sau 1 năm bạn có 50 script tự viết. - Đọc man pages — không đùa. Mỗi tuần đọc 1 cái
mantrọn vẹn. Bạn sẽ phát hiện flag tuyệt vời cho lệnh quen thuộc.