맥에서 파이썬 자동 실행 설정하기 - launchd 완벽 가이드

맥에서 파이썬 스크립트를 정기적으로 실행하려면 launchd를 사용하는 방법이 가장 안정적이에요. cron보다 훨씬 강력하고 macOS에 최적화되어 있죠. 특히 시스템이 절전 모드에 들어가도 작업이 밀리지 않고 제때 실행되는 게 큰 장점이에요.


은색 금속 표면에 새겨진 검은색 애플 로고의 클로즈업 사진


launchd가 뭔가요?


launchd는 macOS 10.4 Tiger부터 도입된 시스템 레벨의 작업 스케줄러예요. 단순히 시간에 따라 작업을 실행하는 것뿐만 아니라, 시스템 이벤트나 파일 변경, 네트워크 연결 등 다양한 조건에 반응해서 프로그램을 실행할 수 있어요.


리눅스나 유닉스를 써보신 분들은 cron이 더 익숙하실 텐데, macOS에서는 cron이 제대로 작동하지 않는 경우가 많아요. 맥북을 닫아두면 cron 작업이 실행되지 않거나, 에너지 절약 모드에서 스케줄이 어긋나는 문제가 자주 발생하죠.


plist 파일 작성하기


launchd를 사용하려면 먼저 plist 파일을 만들어야 해요. plist는 Property List의 약자로, XML 형식으로 작성하는 설정 파일이에요.


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.myname.databackup</string>
    
    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/bin/python3</string>
        <string>/Users/myname/scripts/backup.py</string>
    </array>
    
    <key>StartCalendarInterval</key>
    <dict>
        <key>Hour</key>
        <integer>9</integer>
        <key>Minute</key>
        <integer>30</integer>
    </dict>
    
    <key>StandardOutPath</key>
    <string>/Users/myname/logs/backup.log</string>
    
    <key>StandardErrorPath</key>
    <string>/Users/myname/logs/backup_error.log</string>
</dict>
</plist>


위 예시는 매일 오전 9시 30분에 backup.py를 실행하는 설정이에요. Label은 작업의 고유 이름으로, 보통 역도메인 형식(com.회사명.작업명)으로 작성해요. ProgramArguments는 실행할 명령어와 인자를 배열로 지정하는데, 첫 번째는 파이썬 실행 파일 경로, 두 번째는 스크립트 경로예요.


파이썬 경로 확인하기


plist 파일을 작성하기 전에 파이썬 경로를 정확히 확인해야 해요. 터미널을 열고 다음 명령어를 입력해보세요.


which python3


보통 /usr/local/bin/python3 나 /opt/homebrew/bin/python3 같은 경로가 나올 거예요. 이 경로를 plist 파일에 정확히 입력해야 해요.


다양한 실행 주기 설정하기


매시간 실행하기


<key>StartInterval</key>
<integer>3600</integer>


StartInterval을 사용하면 초 단위로 반복 실행할 수 있어요. 3600초는 1시간이니까 매시간 실행되겠죠.


특정 요일에만 실행하기


<key>StartCalendarInterval</key>
<array>
    <dict>
        <key>Weekday</key>
        <integer>2</integer>
        <key>Hour</key>
        <integer>10</integer>
        <key>Minute</key>
        <integer>0</integer>
    </dict>
    <dict>
        <key>Weekday</key>
        <integer>5</integer>
        <key>Hour</key>
        <integer>10</integer>
        <key>Minute</key>
        <integer>0</integer>
    </dict>
</array>


이렇게 하면 화요일(2)과 금요일(5) 오전 10시에만 실행돼요. 요일 숫자는 일요일이 1, 토요일이 7이에요.


5분마다 실행하기


<key>StartInterval</key>
<integer>300</integer>


300초는 5분이니까 5분마다 반복 실행돼요. 실시간 모니터링이나 데이터 수집 작업에 유용해요.


plist 파일 저장 위치


plist 파일은 용도에 따라 저장 위치가 달라요.


  • 사용자 전용: ~/Library/LaunchAgents/
  • 시스템 전체(관리자 권한): /Library/LaunchAgents/
  • 시스템 데몬(백그라운드): /Library/LaunchDaemons/


대부분의 개인 작업은 사용자 전용 폴더에 저장하면 돼요. 폴더가 없으면 만들어야 해요.


mkdir -p ~/Library/LaunchAgents


파일명은 Label과 맞춰서 com.myname.databackup.plist 형식으로 저장하는 게 관리하기 편해요.


launchctl로 등록하고 관리하기


plist 파일을 저장했으면 launchctl 명령어로 등록해야 해요.


# 등록하기
launchctl load ~/Library/LaunchAgents/com.myname.databackup.plist

# 해제하기
launchctl unload ~/Library/LaunchAgents/com.myname.databackup.plist

# 상태 확인하기
launchctl list | grep com.myname.databackup


plist 파일을 수정했다면 반드시 unload 후 다시 load해야 변경사항이 적용돼요.


환경 변수와 작업 디렉토리 설정


파이썬 스크립트가 특정 경로에서 실행되어야 하거나 환경 변수가 필요한 경우가 있어요.


<key>WorkingDirectory</key>
<string>/Users/myname/projects/data-analysis</string>

<key>EnvironmentVariables</key>
<dict>
    <key>PATH</key>
    <string>/usr/local/bin:/usr/bin:/bin</string>
    <key>PYTHONPATH</key>
    <string>/Users/myname/projects/libs</string>
    <key>API_KEY</key>
    <string>your-secret-api-key</string>
</dict>


WorkingDirectory를 설정하면 스크립트가 해당 폴더에서 실행된 것처럼 작동해요. 상대 경로로 파일을 읽거나 쓸 때 유용하죠.


실행 조건 추가하기


단순히 시간에 따라 실행하는 것 외에도 다양한 조건을 설정할 수 있어요.


<!-- 로그인할 때 실행 -->
<key>RunAtLoad</key>
<true/>

<!-- 프로세스가 종료되면 자동 재시작 -->
<key>KeepAlive</key>
<true/>

<!-- 네트워크 연결 시에만 실행 -->
<key>KeepAlive</key>
<dict>
    <key>NetworkState</key>
    <true/>
</dict>


RunAtLoad를 true로 설정하면 맥에 로그인할 때마다 스크립트가 실행돼요. KeepAlive는 프로세스가 비정상 종료되었을 때 자동으로 재시작하는 기능이에요.


주식 데이터 수집기


실제로 사용할 만한 예제를 만들어볼게요. 매일 오후 4시에 주식 데이터를 수집하는 스크립트를 자동 실행하는 설정이에요.


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.mytrading.stockcollector</string>
    
    <key>ProgramArguments</key>
    <array>
        <string>/opt/homebrew/bin/python3</string>
        <string>/Users/myname/trading/collect_stock_data.py</string>
        <string>--market</string>
        <string>KRX</string>
    </array>
    
    <key>StartCalendarInterval</key>
    <dict>
        <key>Weekday</key>
        <integer>2</integer>
        <key>Hour</key>
        <integer>16</integer>
        <key>Minute</key>
        <integer>0</integer>
    </dict>
    <!-- 화요일부터 토요일까지 반복 -->
    
    <key>WorkingDirectory</key>
    <string>/Users/myname/trading</string>
    
    <key>EnvironmentVariables</key>
    <dict>
        <key>STOCK_API_KEY</key>
        <string>your-api-key-here</string>
        <key>DATABASE_URL</key>
        <string>postgresql://localhost/stockdb</string>
    </dict>
    
    <key>StandardOutPath</key>
    <string>/Users/myname/trading/logs/collect.log</string>
    
    <key>StandardErrorPath</key>
    <string>/Users/myname/trading/logs/collect_error.log</string>
    
    <key>StartInterval</key>
    <integer>86400</integer>
</dict>
</plist>


디버깅과 문제 해결


스크립트가 제대로 실행되지 않을 때는 로그 파일을 확인하는 게 첫 번째예요.


# 실시간 로그 확인
tail -f /Users/myname/logs/backup_error.log

# launchd 시스템 로그 확인
log show --predicate 'subsystem == "com.apple.xpc.launchd"' --last 1h


가장 흔한 문제들과 해결 방법을 정리해볼게요.


파이썬 경로 문제: which python3로 확인한 경로와 plist에 입력한 경로가 다른 경우가 많아요. 특히 가상환경을 사용한다면 절대 경로를 정확히 입력해야 해요.


권한 문제: 스크립트가 접근하려는 파일이나 폴더에 대한 권한이 없을 수 있어요. chmod로 권한을 조정하거나 스크립트 내에서 예외 처리를 해주세요.


모듈 import 오류: launchd로 실행할 때는 터미널에서 실행할 때와 환경이 달라요. sys.path를 출력해서 경로를 확인하고, 필요하면 PYTHONPATH를 설정해주세요.


GUI 도구 활용하기


XML을 직접 편집하는 게 부담스럽다면 GUI 도구를 사용할 수도 있어요. LaunchControl이나 Lingon 같은 앱을 사용하면 마우스 클릭만으로 plist 파일을 만들 수 있어요. 유료 앱이지만 복잡한 스케줄을 자주 관리한다면 투자할 만한 가치가 있어요.


보안 고려사항


launchd로 실행되는 스크립트는 시스템 권한으로 동작할 수 있기 때문에 보안에 신경 써야 해요.


API 키나 비밀번호는 plist 파일에 직접 넣지 말고, 별도의 설정 파일이나 macOS 키체인을 사용하세요. 또한 스크립트 파일의 권한을 적절히 설정해서 다른 사용자가 수정할 수 없도록 해야 해요.


chmod 700 /Users/myname/scripts/backup.py


launchd는 처음엔 복잡해 보이지만, 한 번 익숙해지면 정말 강력한 도구예요. 특히 맥을 주 개발 환경으로 사용한다면 반드시 알아두어야 할 기능이죠. 데이터 백업, 로그 정리, API 데이터 수집 등 반복적인 작업을 자동화하면 생산성이 크게 향상될 거예요.


Mac에서 5분마다 자동으로 스크린샷 찍는 방법: cron과 screencapture 완벽 가이드