Cách dùng Launchd để lên lịch chạy Script trên máy Mac

Tự động hóa các tác vụ bằng cách lên lịch các Script là một khả năng mạnh mẽ mà nhiều Quản trị viên sử dụng hàng ngày. Người dùng Mac thông thường cũng có thể khai thác sức mạnh này bằng cách sử dụng launchd, công cụ ưa thích của Apple để quản lý và tự động hóa tác vụ trên macOS. Từ việc lên lịch các tác vụ đơn giản như tắt WiFi vào một giờ cụ thể đến chạy các bản sao lưu hệ thống phức tạp, launchd trên máy Mac có thể giúp bạn tự động hóa quy trình công việc, tiết kiệm thời gian và đảm bảo rằng hệ thống chạy theo cách bạn muốn.

Launchd là gì?

Giống như một dàn nhạc cần có một nhạc trưởng để hướng dẫn và hòa âm các nhạc cụ đa dạng, macOS Ventura , với vô số quy trình và dịch vụ, dựa vào launchd để đảm bảo mọi thứ chơi trong một buổi hòa nhạc hoàn hảo. Là quy trình đầu tiên được khởi chạy bởi nhân macOS khi bạn khởi động máy tính của mình, launchd chiếm vị trí trung tâm, điều phối mọi quy trình, dịch vụ và ứng dụng tiếp theo, giống như một nhạc trưởng báo hiệu phần đầu của một bản giao hưởng bằng tiếng dùi cui ban đầu.

Ngoài vai trò điều phối hệ thống, launchd có thể được sử dụng để lên lịch cho các Script, một loạt các lệnh được viết để thực hiện một tác vụ cụ thể. Điều này được thực hiện bằng cách sử dụng lệnh  launchctl, đóng vai trò là giao diện để người dùng giao tiếp và chỉ đạo dây dẫn được khởi chạy.

Daemon và Agent

Launchd đôi khi được gọi là daemon, một chương trình máy tính chạy dưới dạng quy trình nền và thường không được thiết kế để người dùng trực tiếp kiểm soát. Các trình tiện ích con này chạy dưới quyền của người dùng root, vì vậy chúng có thể làm bất cứ điều gì.

Quảng cáo
Đồ họa Wiki của Quỷ Maxwell
Nguồn hình ảnh: Wikipedia

Tuy nhiên, với tư cách là người dùng quan tâm đến lập lịch tác vụ, việc chạy Script dưới quyền root user không phải lúc nào cũng mong muốn hoặc cần thiết. Đây là nơi các Agent phát huy tác dụng. Agent chạy thay mặt cho người dùng đã đăng nhập, cung cấp một môi trường hạn chế hơn và đảm bảo rằng các Script hoặc tác vụ được thực hiện với quyền và tùy chọn của người dùng cụ thể đó. Chẳng hạn, nếu bạn muốn chạy một Script để thay đổi cài đặt hoặc truy cập các file trong tài khoản của mình, thì bạn sẽ sử dụng một Agent.

Viết Script

Để chạy các agent hoặc daemon thông qua launchd, bạn sẽ cần viết một số Script, ngôn ngữ Script phổ biến nhất là bash.

launchd-code-scriptto

Các launchd Script có thể tồn tại ở hai vị trí khác nhau, tùy thuộc vào việc chúng được chạy dưới dạng agent hay daemon:

Quảng cáo
  • Đối với những Script có nghĩa là Agent, hành động thay mặt cho người dùng đã đăng nhập, chúng phải được lưu trữ trong “~/Library/LaunchAgents.”
  • Ngược lại, các Script nhằm hoạt động như daemon, trên toàn hệ điều hành bất kể người dùng đã đăng nhập là ai, thuộc về “/Library/LaunchDaemons.”

Hãy nhớ rằng, các agent không có quyền root, vì vậy agent không thể thực hiện các tác vụ yêu cầu quyền truy cập sâu vào hệ thống. Mặt khác, daemon chạy với quyền root và có thể xử lý các tác vụ ảnh hưởng đến toàn bộ hệ thống.

Mô tả Job

launchd-scripts-job-mô tả

Các Script trong launchd được kích hoạt bởi các định nghĩa job, là các file .plist được lưu trữ trong các thư mục cụ thể. Các file XML này đặt tên cho job, chỉ định Script sẽ được khởi chạy và cho biết khi nào Script sẽ được chạy. Khi bạn đã viết Script của mình, bạn sẽ viết và tải định nghĩa job để khởi chạy Script vào thời điểm thích hợp. Một định nghĩa job trông giống như thế này:

<?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>local.restart</string>
        <key>Program</key>
        <string>/Users/user/Scripts/restart.sh</string>
        <key>RunAtLoad</key>
        <true/>
    </dict>
</plist>

Sửa đổi nếu cần, sau đó đặt nó vào một file văn bản có phần mở rộng .plist trước khi thả nó vào đúng thư mục (xem bên trên).

Có một vài phần chính trong bản mô tả job:

  • Label: tên của job trong launchd. Phải là duy nhất cho mỗi job. Chúng được viết bằng ký hiệu miền đảo ngược và “cục bộ” là một miền tốt nhất cho các Private Agent.
  • Program: đường dẫn đầy đủ của Script mà mô tả job này khởi chạy.
  • RunAtLoad: mô tả khi nào Script sẽ được chạy. Có một vài lựa chọn khác nhau ở đây:
    • RunAtLoad : chạy ngay khi định nghĩa job được tải. Chỉ chạy một lần cho mỗi lần tải.
    • StartInterval : bắt đầu job cứ sau n giây. Ví dụ này sẽ chạy job sau mỗi 7200 giây hoặc cứ sau 2 giờ.<key > StartInterval </key > < integer > 7200 </integer>
    • StartCalendarInterval : chạy job vào ngày giờ cụ thể. Mã dưới đây sẽ chạy job hàng ngày lúc 9 giờ sáng.<key > StartCalendarInterval </key > <dict > <key > Giờ </key > < integer > 9 </integer > <key > Minute </key > <integer > 0 </integer > </dict>

Tải job vào launchctl

Khi bạn đã tạo Script của mình và lưu agent của mình vào đúng chỗ, bạn sẽ cần tải Script đó vào file launchctl. Điều này sẽ tự động xảy ra khi đăng nhập trong tương lai.

Để xem những gì hiện đang chạy trong laucnhctl, bạn có thể sử dụng launchctl list trong terminal. Danh sách khổng lồ này có thể được thêm vào Script bằng cách gắn nhãn cho nó bằng nội dung nào đó như sau:

launchctl list | grep local.restart

Để tải Script, hãy mở Terminal và sử dụng lệnh sau:

Quảng cáo
launchctl load ~/Library/LaunchAgents/local.restart.plist/ local.restart.plist
launchd-scripts-launchctl-load

Để xóa Script khỏi hàng đợi launchctl, hãy sử dụng lệnh  unload:

launchctl unload ~/Library/LaunchAgents/local.restart.plist
launchd-scripts-launchctl-unload

Tải một job sẽ đặt nó vào hàng đợi launchd và job sẽ chạy vào thời điểm được chỉ định trong các điều kiện khởi chạy của nó. Nếu bạn muốn chạy Script ngay lập tức bất kể điều gì, bạn nên sử dụng lệnh “start”:

launchctl start local.restart

Lệnh này lấy nhãn của job và sẽ chỉ hoạt động nếu job đã được tải vào file launchctl.

Các câu hỏi thường gặp

Làm sao kiểm tra xem launchd đã bắt đầu Script chưa?

Bạn có thể sử dụng  lệnh launchctl list trong terminal. Thao tác này sẽ hiển thị tất cả các job đã tải. Để tìm một Script hoặc job cụ thể, hãy sử dụng grep, ví dụ: launchctl list | grep your_script_name.

Nếu launchd đang sử dụng quá nhiều tài nguyên hệ thống thì sao?

Nếu launchd đang tiêu tốn quá nhiều tài nguyên, thì đó thường là do Script hoặc tác vụ hoạt động sai. Bạn nên xem lại các Script bạn đã thêm gần đây và hủy tải chúng bằng cách sử dụng launchctl unload /path/to/job.plist.

Sự khác biệt giữa cron và launchd là gì?

Cả cron và launchd đều là dịch vụ lập lịch trình, nhưng chúng hoạt động khác nhau. cron là một công cụ lập lịch job dựa trên Unix cũ hơn, chạy các job vào các thời điểm hoặc khoảng thời gian cố định được xác định trong file crontab. launchd là hệ thống mới hơn của Apple dành cho macOS có thể bắt đầu job dựa trên nhiều trình kích hoạt khác nhau – không chỉ thời gian.

Tôi có thể sử dụng các ngôn ngữ Script khác ngoài bash với launchd không?

launchd có thể thực thi bất kỳ Script nào có thể chạy từ terminal. Điều này bao gồm các Script được viết bằng Python, Perl, Ruby và các ngôn ngữ khác.

Quảng cáo