Ngăn Mac ngủ khi đang chạy lệnh Terminal dài

Trả lời nhanh: thêm caffeinate -i your-command hoặc lidrun -- your-command vào trước lệnh của bạn, Mac sẽ thức cho tới khi lệnh chạy xong, không cần ngồi canh. Điều mà hầu hết hướng dẫn bỏ qua là gập nắp máy lại hoạt động theo một cơ chế hoàn toàn khác — cả caffeinate lẫn một assertion keep-awake thông thường đều không chặn được việc đó, và đây chính là điểm khiến nhiều người chạy job dài không giám sát bị dính.
Vì sao lệnh chạy dài bị cắt ngang
Một lệnh chạy trong Terminal là một process bình thường, gắn với trạng thái nguồn của Mac. Rời máy đủ lâu để chạm hẹn giờ idle, hoặc gập nắp lại, Mac sẽ ngủ và lệnh bị treo giữa chừng.
Các lệnh rsync chuyển file lớn, build, tải model, hay chạy batch script là những thứ dễ chạy lâu hơn hẹn giờ idle nhất — và cũng chính là những lệnh bạn ít muốn chạy lại nhất. Job không hề lỗi — chỉ là Mac dừng lại ngay dưới chân nó.
Còn một kiểu lỗi thứ hai, liên quan, đáng nói trước: nếu bạn SSH vào một Mac để chạy job từ xa, chiếc máy đó có hẹn giờ idle và gập nắp riêng của nó, hoàn toàn độc lập với kết nối SSH. Công cụ giữ máy thức phải chạy trên chính máy đang làm việc, không phải trên máy bạn đang gõ lệnh.
caffeinate và các flag của nó
macOS có sẵn caffeinate cho đúng việc này, và với một job foreground đơn lẻ thì đây là công cụ đúng đắn — không cần cài, không tốn phí. Tổ hợp flag sẽ quyết định nó thực sự giữ mở cái gì:


caffeinate -i your-command — chặn idle sleep suốt thời gian your-command chạy, xong tự thoát và tự giải phóng. Đây là lựa chọn hầu hết mọi người cần cho một job trong Terminal.
caffeinate -d your-command — giữ cả màn hình sáng, hữu ích nếu bạn muốn liếc qua output đang chạy mà không lo màn hình mờ đi.
caffeinate -s your-command — chặn system sleep, nhưng chỉ khi Mac đang cắm sạc. Chạy bằng pin, -s lặng lẽ không làm gì cả, điều khiến không ít người bất ngờ vì tưởng nó hoạt động giống nhau dù cắm điện hay không.
caffeinate -w <pid> — không bọc lệnh nào cả; nó chờ một process đã đang chạy sẵn. Tiện cho job bạn vừa chạy nền: long_job & caffeinate -w $!.
caffeinate -t 3600 — giữ assertion trong một số giây cố định thay vì gắn với process, hữu ích khi bạn cần một khung thời gian định trước hơn là một lệnh cụ thể.
Hướng dẫn liên quanNgăn Mac ngủ trong lúc build DockerGiới hạn của caffeinate, và vì sao nắp máy là chuyện khác
Điều caffeinate không làm là theo dõi pin hay nhiệt độ. Bất kỳ flag nào ở trên cũng sẵn sàng giữ laptop thức cho tới khi cạn pin, ngay cả khi bạn không có mặt để thấy job chạy, và không flag nào đọc trạng thái nhiệt của Mac trong một lần compile dài và nóng.


Nắp máy lại là một chuyện khác hẳn. Các assertion của caffeinate, và cùng lệnh gọi IOPMAssertionCreateWithName mà CLI của LidRun dùng, chỉ chặn được sleep *idle*. Gập nắp lại sẽ kích hoạt một kiểu clamshell sleep riêng, ở tầng thấp hơn, mà không assertion idle-sleep nào chặn được — hệ điều hành vẫn cho máy ngủ bất kể. Đòn bẩy công khai duy nhất giữ một Mac gập nắp thức khi chạy pin là pmset -a disablesleep 1, một cài đặt hệ thống toàn cục, cần quyền admin; nếu có màn hình ngoài đang kết nối và hoạt động, macOS cũng tự thức qua chế độ clamshell gốc, không cần công cụ bên thứ ba nào. Nếu tình huống thực tế của bạn là gập nắp máy chứ không phải ngồi tại bàn, hướng dẫn về chế độ gập nắp của chúng tôi nói kỹ về cơ chế này và các đánh đổi của nó — bài viết này chỉ tập trung vào trường hợp chạy lệnh Terminal.
Chạy job dài qua SSH
Khi lệnh chạy trên một Mac từ xa, có hai chiếc đồng hồ cần quan tâm, và chúng độc lập với nhau. Một là hẹn giờ idle-sleep của chính Mac đó; hai là liệu phiên SSH của bạn có sống sót qua một trục trặc mạng hay việc đóng terminal cục bộ hay không.
Với vấn đề đầu tiên, chạy caffeinate -i hoặc lidrun -- ngay trên chính Mac từ xa, không phải trên máy cục bộ của bạn — một assertion keep-awake chỉ bảo vệ được cái máy nó đang chạy trên đó.
Với vấn đề thứ hai, bọc lệnh từ xa trong nohup, screen, hoặc tmux trước khi bạn ngắt kết nối. Không có một trong ba thứ đó, việc đóng terminal cục bộ (hoặc mất kết nối) có thể gửi SIGHUP tới shell từ xa và giết job dù bản thân Mac chưa hề ngủ.
Cách bọc lệnh an toàn hơn
CLI của LidRun dùng cùng kiểu bọc-một-lệnh này, nhưng thêm vào những lớp bảo vệ mà caffeinate bỏ qua: lidrun -- your-command giữ một assertion keep-awake ngắn hạn cho đúng lần chạy đó và giải phóng ngay khi lệnh kết thúc, không cần license hay cài đặt gì thêm — miễn phí và không giới hạn, y như caffeinate.
Trong lúc assertion đó còn hiệu lực, ngưỡng pin tối thiểu và cơ chế tự nhả khi quá nhiệt của app vẫn áp dụng nếu LidRun đang chạy: keep-awake tự dừng ở một mức pin bạn đặt (mặc định 20%, chỉnh được 15–50%), và có một ngưỡng khẩn cấp cứng ở 4% luôn kích hoạt bất kể bạn đặt gì, vì macOS cần đúng ngần đó dư địa để ngủ trọn vẹn. Nếu trạng thái nhiệt của Mac chạm mức critical, việc giữ máy thức cũng mặc định tự nhả — lời hứa thành thật của LidRun là: agent hay job còn chạy thì giữ máy thức; job xong hoặc Mac không còn an toàn thì nhả ra và để máy ngủ.
Bên trong app cũng có một phiên bản GUI cho việc này — bảng Run & Watch khởi chạy một lệnh, giữ Mac thức trong lúc đó, và hiển thị output trực tiếp mà bạn không cần đụng tới Terminal — nhưng bảng đó là tính năng Pro. Riêng CLI wrapper lidrun -- <command> thuần túy thì không bị khóa chút nào; nó nằm trong gói miễn phí của LidRun.
Một cách thiết lập thực tế
Chạy một lệnh đơn lẻ, ngồi tại bàn: thêm tiền tố rồi cứ đi làm việc khác — lidrun -- your-long-command hay caffeinate -i your-long-command đều được, và assertion sẽ nhả ngay khi lệnh chạy xong. Cả hai không cần thiết lập gì thêm.
Phiên chạy dài, không giám sát, vẫn mở nắp máy: cắm sạc nếu có thể, chạy lệnh, và nếu bạn muốn các lớp bảo vệ pin/nhiệt của LidRun theo dõi cả phiên chứ không chỉ một process, hãy bật công tắc Keep Awake trên menu bar trước, rồi chạy lệnh như bình thường. Đặt một session timer (bộ chọn có từ 30 phút tới 8 giờ) để một script bị treo không giữ Mac thức vô thời hạn — một job bị treo chính là trường hợp mà một keep-awake không giám sát không nên chạy mãi mãi.
Phiên chạy khi gập nắp: trường hợp này cần đúng chế độ Closed-Lid, không phải một keep-awake thông thường — xem hướng dẫn riêng đã dẫn ở trên, vì nó thay đổi hẳn bài toán an toàn (nhiệt không có đường thoát khi nắp đóng).
Dù thiết lập thế nào, hãy đặt Mac trên một mặt phẳng cứng, thoáng khí khi chạy các job nặng. Một lần build, nén file, hay chuyển dữ liệu dài có thể khiến máy chạy nóng, và luồng khí là thứ duy nhất không cài đặt phần mềm nào sửa được.
LidRun giữ công việc của bạn chạy tiếp khi đóng nắp, với cơ chế bảo vệ pin và nhiệt tích hợp sẵn.
Đã có LidRun? Đọc hướng dẫn thiết lập →
Mới biết đến LidRun? Xem bảng giá →
Câu hỏi thường gặp
Với một job trên Mac đang cắm sạc mà bạn sẽ ghé kiểm tra, thì có — caffeinate -i your-command đáng tin cậy và miễn phí. Với một job dài không giám sát, nhất là chạy bằng pin, nó không hề biết gì về pin hay nhiệt độ, nên sẽ cứ giữ Mac thức thẳng cho tới lúc pin cạn buộc phải tắt máy, hoặc job chạy nóng tới mức bị throttle.
-i chặn idle sleep cho lệnh được bọc (đây là cái hầu hết job Terminal cần), -d giữ luôn cả màn hình sáng, -s chặn system sleep nhưng chỉ khi cắm sạc (không có tác dụng gì khi chạy pin), và -w <pid> chờ một process đã đang chạy sẵn thay vì bọc một lệnh mới.
Được. Cả caffeinate -i your-command lẫn lidrun -- your-command đều giữ một assertion idle-sleep trong suốt thời gian process đó chạy và tự giải phóng khi lệnh kết thúc. CLI wrapper lidrun miễn phí và không giới hạn, không cần license.
caffeinate và một assertion keep-awake thông thường chỉ chặn được idle sleep. Gập nắp lại kích hoạt một kiểu clamshell sleep riêng mà assertion idle-sleep không chặn được — Mac cần hoặc một màn hình ngoài đang hoạt động, hoặc cài đặt pmset -a disablesleep 1 cần quyền admin (chính là thứ chế độ Closed-Lid của LidRun dùng) để thức khi nắp đóng.
Nếu bạn dùng chế độ Keep Awake của LidRun với session timer đã đặt, timer sẽ giới hạn thời gian chạy — từ 30 phút tới 8 giờ — để một lệnh bị treo không giữ Mac thức vô thời hạn. Bọc lệnh bằng caffeinate -i thuần túy thì không có giới hạn đó; nó cứ giữ cho tới khi process thoát hoặc bạn tự tay kill nó.
Công cụ keep-awake cần chạy trên chính chiếc Mac đang làm việc, không phải máy cục bộ của bạn — SSH không thay đổi hẹn giờ sleep của riêng chiếc Mac đó. Tách biệt với chuyện đó, hãy bọc lệnh từ xa trong nohup, screen, hoặc tmux để một kết nối bị rớt hay terminal cục bộ bị đóng không gửi SIGHUP và giết job, ngay cả khi Mac từ xa vẫn thức.