반응형

바쁜 분은 이것만

  1. 오래 걸리는 명령 앞에 caffeinate -i를 붙이면 그 명령이 끝날 때까지만 잠자기를 막아요
  2. 시간으로 막으려면 caffeinate -t 3600(초 단위), 화면까지 켜 두려면 -d
  3. 정말 걸렸는지는 pmset -g assertions | grep caffeinate로 확인

예전에 맥 crontab이 실행 안 될 때 (잠자기 중이면 그냥 건너뛴다)에서 맥이 잠들어 있으면 예약 작업이 그냥 지나간다는 걸 봤어요. 반대로 지금 돌리는 작업이 길 때는 중간에 맥이 잠들지 않게 해야 하는데, 이때 쓰는 게 맥에 기본으로 들어 있는 caffeinate 명령입니다. 설치할 것도 없고 설정 화면을 바꾸지도 않아요.

1. 가장 간단한 사용: caffeinate -t 초

-t 뒤에 숫자를 주면 그 초 동안만 잠자기를 막고 저절로 끝나요. 10초만 걸고, 맥이 실제로 기록하고 있는지 pmset -g assertions로 봤습니다. 이 명령은 지금 잠자기를 막고 있는 프로세스를 전부 보여 주기 때문에, 제 caffeinate의 PID 줄만 grep으로 골랐어요.

caffeinate -d -i -t 10 &
CPID=$!
echo "caffeinate PID: $CPID"
sleep 1
echo "--- pmset -g assertions (이 PID 줄만)"
pmset -g assertions | grep "pid $CPID("
sleep 11
echo "--- 11초 뒤"
pmset -g assertions | grep "pid $CPID(" || echo "(이 PID의 assertion 없음)"
ps -p $CPID > /dev/null || echo "caffeinate 종료됨"
caffeinate PID: 84954
--- pmset -g assertions (이 PID 줄만)
   pid 84954(caffeinate): [0x00022d130001803c] 00:00:01 PreventUserIdleSystemSleep named: "caffeinate command-line tool"
   pid 84954(caffeinate): [0x00022d140005803d] 00:00:01 PreventUserIdleDisplaySleep named: "caffeinate command-line tool"
--- 11초 뒤
(이 PID의 assertion 없음)
caffeinate 종료됨
  • 맥에서는 "잠들지 마"라는 요청을 assertion이라고 불러요. -i는 PreventUserIdleSystemSleep, -d는 PreventUserIdleDisplaySleep으로 찍힙니다.
  • 00:00:01은 걸린 지 지난 시간이에요. 10초가 지나니 줄이 사라지고 caffeinate도 끝났어요.
  • 1시간이면 -t 3600, 2시간이면 -t 7200입니다.

2. -d, -i, -s, -u 차이

man caffeinate의 설명을 옮기면 이렇습니다(영어 원문 일부).

-d      Create an assertion to prevent the display from sleeping.
-i      Create an assertion to prevent the system from idle sleeping.
-s      Create an assertion to prevent the system from sleeping. This
        assertion is valid only when system is running on AC power.
-u      Create an assertion to declare that user is active. ...
        If a timeout is not specified with '-t' option, then this
        assertion is taken with a default of 5 second timeout.

옵션을 하나씩 3초짜리로 걸고 어떤 이름으로 찍히는지 봤어요(앞의 PID·ID는 sed로 지웠습니다).

for opt in -d -i -s -u -m; do
  caffeinate $opt -t 3 &
  CPID=$!
  sleep 0.5
  echo "[caffeinate $opt]"
  pmset -g assertions | grep "pid $CPID(" | sed -E 's/^ +pid [0-9]+\(caffeinate\): \[0x[0-9a-f]+\] [0-9:]+ /  /; s/ +$//'
  kill $CPID 2>/dev/null; wait $CPID 2>/dev/null
done
[caffeinate -d]
  PreventUserIdleDisplaySleep named: "caffeinate command-line tool"
[caffeinate -i]
  PreventUserIdleSystemSleep named: "caffeinate command-line tool"
[caffeinate -s]
  PreventSystemSleep named: "caffeinate command-line tool"
[caffeinate -u]
  UserIsActive named: "caffeinate command-line tool"
[caffeinate -m]
  PreventDiskIdle named: "caffeinate command-line tool"
  • -i: 아무것도 안 만지고 있어서 생기는 자동 잠자기(idle sleep)를 막아요. 화면은 꺼질 수 있어요. 스크립트 돌릴 때는 보통 이것 하나면 됩니다.
  • -d: 화면이 꺼지는 것을 막아요. 진행 상황을 화면으로 계속 봐야 할 때.
  • -s: 시스템 잠자기를 막는데 man page대로 전원 어댑터(AC)를 꽂아 둔 상태에서만 유효해요. 이 테스트는 배터리로 돌렸는데도 목록에는 떴으니, "목록에 보인다 = 효과가 있다"는 아니라는 점만 기억해 두세요.
  • -u: "사용자가 지금 쓰고 있다"고 알려서 꺼진 화면을 켜요. -t가 없으면 5초짜리예요.
  • -m: 디스크 idle 잠자기 방지(덤으로 확인).

옵션 없이 caffeinate -t 3만 주면 어떻게 될까요? man page에 "옵션이 없으면 idle sleep을 막는다"고 되어 있고, 실제로도 -i와 같은 줄이 나왔어요.

   pid 97310(caffeinate): 00:00:00 PreventUserIdleSystemSleep named: "caffeinate command-line tool"

3. caffeinate -i 파이썬 스크립트: 끝나면 저절로 풀린다

제일 쓸모 있는 방법이에요. 실행할 명령을 caffeinate 뒤에 그대로 붙이면 그 명령이 도는 동안만 잠자기를 막고, 끝나면 같이 풀립니다. 오래 걸리는 작업 대신 5초짜리 스크립트로 확인했어요.

# job.py — 5초 동안 1초마다 출력
import time, datetime as dt
for i in range(1, 6):
    print(f"{dt.datetime.now():%H:%M:%S} 작업 {i}/5", flush=True)
    time.sleep(1)
print("끝", flush=True)
caffeinate -i ~/work/.venv/bin/python job.py &
CPID=$!
sleep 2
JPID=$(pgrep -P $CPID)
echo "--- 실행 중 (caffeinate PID $CPID, 파이썬 PID $JPID)"
pmset -g assertions | grep -E "pid ($CPID|$JPID)\(" | sed -E 's/\[0x[0-9a-f]+\] //; s/ +$//'
wait $CPID
echo "--- 끝난 뒤"
pmset -g assertions | grep -E "pid ($CPID|$JPID)\(" || echo "(이 PID들의 assertion 없음)"
00:16:10 작업 1/5
00:16:11 작업 2/5
--- 실행 중 (caffeinate PID 92223, 파이썬 PID 92225)
00:16:12 작업 3/5
   pid 92225(caffeinate): 00:00:02 PreventUserIdleSystemSleep named: "caffeinate command-line tool"
00:16:13 작업 4/5
00:16:14 작업 5/5
끝
--- 끝난 뒤
(이 PID들의 assertion 없음)
  • 재미있는 점: assertion이 caffeinate PID(92223)가 아니라 파이썬 PID(92225) 앞으로 잡혀 있어요. man page의 "utility를 대신해서(on the utility's behalf)" 건다는 말 그대로예요. 처음에 caffeinate PID로만 grep했더니 아무것도 안 나와서 알게 됐습니다.
  • 스크립트가 끝나자 줄이 사라졌어요. 풀어 주는 걸 깜빡할 일이 없습니다.
  • 이렇게 명령을 붙여 쓰면 -t는 무시돼요(man: "Timeout value is not used when an utility is invoked").

launchd로 정해진 시각에 도는 스크립트(맥 launchd 자동 실행 스크립트가 가끔 빠질 때)도 실행 명령 앞에 /usr/bin/caffeinate -i를 붙이면 도는 동안은 잠들지 않게 할 수 있어요.

4. 이미 돌고 있는 작업에 걸기: -w PID

작업을 먼저 시작해 버렸다면 그 PID를 -w로 넘기면 돼요. 그 프로세스가 끝날 때 caffeinate도 같이 끝납니다. 6초 걸리는 파이썬을 띄우고 걸어 봤어요.

~/work/.venv/bin/python -c "import time; time.sleep(6)" &
JPID=$!
caffeinate -i -w $JPID &
CPID=$!
sleep 1
echo "작업 PID $JPID / caffeinate PID $CPID"
pmset -g assertions | grep "pid $CPID(" | sed -E 's/\[0x[0-9a-f]+\] //; s/ +$//'
wait $JPID
sleep 1
echo "--- 작업 끝난 뒤"
ps -p $CPID > /dev/null && echo "caffeinate 아직 실행 중" || echo "caffeinate도 종료됨"
pmset -g assertions | grep "pid $CPID(" || echo "(이 PID의 assertion 없음)"
작업 PID 94819 / caffeinate PID 94820
   pid 94820(caffeinate): 00:00:01 PreventUserIdleSystemSleep named: "caffeinate command-line tool"
--- 작업 끝난 뒤
caffeinate도 종료됨
(이 PID의 assertion 없음)

PID는 pgrep -f 스크립트이름이나 활성 상태 보기 앱에서 찾을 수 있어요. 이 경우는 3번과 달리 assertion이 caffeinate 자기 PID로 잡혀요.

5. 시간 제한 없이 켜 두고 kill로 끄기

옵션만 주고 -t도 명령도 없으면 caffeinate를 직접 끌 때까지 계속 막아요. 터미널에서는 Ctrl+C로 끄면 되고, 뒤에 &를 붙여 백그라운드로 돌렸다면 kill PID로 끕니다.

caffeinate -d &
CPID=$!
sleep 1
jobs -l
pmset -g assertions | grep "pid $CPID(" | sed -E 's/\[0x[0-9a-f]+\] //; s/ +$//'
kill $CPID
wait $CPID
echo "kill 후 종료 코드: $?"
pmset -g assertions | grep "pid $CPID(" || echo "(이 PID의 assertion 없음)"
[1]  + 96270 running    caffeinate -d
   pid 96270(caffeinate): 00:00:01 PreventUserIdleDisplaySleep named: "caffeinate command-line tool"
kill 후 종료 코드: 143
(이 PID의 assertion 없음)

종료 코드 143은 128 + 15(SIGTERM)로, kill로 끝났다는 뜻이에요. 같은 터미널이면 kill %1처럼 작업 번호로 꺼도 됩니다. 이렇게 켜 둔 걸 잊어버리면 계속 안 자니, 웬만하면 3번처럼 명령을 붙이거나 -t를 주는 쪽을 권해요.

정리

명령 언제 풀리나 pmset에 찍히는 이름
caffeinate -i -t 3600 3600초 뒤 PreventUserIdleSystemSleep
caffeinate -d Ctrl+C / kill PreventUserIdleDisplaySleep
caffeinate -s Ctrl+C / kill (AC 전원일 때만 유효) PreventSystemSleep
caffeinate -u 기본 5초 UserIsActive
caffeinate -i python job.py 스크립트가 끝날 때 PreventUserIdleSystemSleep (파이썬 PID)
caffeinate -i -w PID 그 PID가 끝날 때 PreventUserIdleSystemSleep

참고: Apple caffeinate(8) man page (man caffeinate) / pmset(1) man page — -g assertions

반응형

+ Recent posts