상시 켜둔 맥에서 예약 작업을 돌립니다. 이 함정들은 실패가 진짜 원인을 가리키지 않아 각각 디버깅 세션을 잡아먹었습니다.
1. ps -o etimes는 macOS에 없다
BSD ps엔 etimes 키워드가 없습니다 — 리눅스 procps 전용. ps -p PID -o etime=을 쓰고 [[DD-]HH:]MM:SS 형식을 파싱하세요. 리눅스에서 되는 코드가 여기선 조용히 실패합니다.
2. 한국어 로케일에서 pgrep이 실패한다
셸 로케일이 ko_KR.UTF-8이면 pgrep -f <pattern>이 illegal byte sequence를 냅니다. 서브프로세스에 C 로케일을 강제하세요:
env = {**os.environ, "LC_ALL": "C", "LANG": "C"}
subprocess.run([...], env=env)3. launchd의 PATH엔 /usr/sbin이 없다
PATH=/usr/local/bin:/usr/bin:/bin plist는 /usr/sbin/lsof를 못 찾습니다 — FileNotFoundError. lsof·dscl·vm_stat·sysctl 등은 절대경로를 쓰거나 plist PATH에 /usr/sbin을 추가하세요.
4. pgrep -f는 작업 디렉토리를 매칭 안 한다
macOS pgrep -f는 풀 커맨드라인만 보고 cwd는 안 봅니다. 작업 디렉토리로만 식별되는 봇(특정 폴더의 python main.py)은 lsof -a -p PID -d cwd 후처리 필터가 필요합니다.
5. 로그인 화면에선 LaunchAgent가 기동 안 한다
재부팅 후 맥이 macOS 로그인 화면에 머물면 gui/501 도메인이 없어 LaunchAgent가 하나도 로드되지 않습니다 — 모든 예약 작업 다운. SSH로 bootstrap도 안 됩니다(I/O 에러로 실패). 우회는 누군가 로그인할 때까지 plist 명령을 nohup으로 수동 재현 — 그리고 진짜 launchd가 기동하면 스스로 종료하는 감독 스크립트.
솔직한 부분
전부 같은 모양입니다: 도구가 launchd의 최소 환경·비C 로케일·BSD 유저랜드에서 제 인터랙티브 셸과 다르게 동작하는데 — 에러는 제 코드를 탓합니다. 예약 작업이 실패하는데 같은 명령이 터미널에선 되면, 로직이 아니라 환경을 의심하세요: PATH, 로케일, GUI 세션, BSD-vs-GNU 플래그 순으로.