기타

launchctl로 주기적으로 프로그램 실행시키기

Phililip
728x90

안녕하세요.

 

최근에 원하는 시간마다 스크립트를 실행시키고 싶은 적이 있었습니다.

 

그걸 위해 서버를 띄우기는 귀찮았어서... 이런저런 방법을 찾던 중에 launchctl 이란 것을 알게 되었습니다ㅎㅎ

 

한번 알아볼까요?


# 개요

macOS에서 사용 가능합니다. (윈도우에서도 쓸 수 있는지는 잘 모르겠어요...)

 

대략적인 사용법은 아래와 같습니다.

1) plist 파일을 생성해서, 그 plist 파일 안에 주기적으로 프로그램을 실행시키는데 필요한 정보들을 입력해 줍니다.
(여기서 말하는 정보란, 몇 분마다 실행시킬지, 어떤 프로그램을 실행시킬지 같은 정보를 의미합니다.)
2) launchctl 명령어로 plist 파일을 LaunchAgents라는 곳에 등록(load)시킵니다.
3) 등록한 plist 정보를 바탕으로 프로그램이 자동으로 실행됩니다.

 

직접 써볼게요^^

 

 

# 사용방법

예시로, 30초마다 자동으로 스크립트를 실행시키도록 설정해 볼게요.

 

 

일단 스크립트 하나를 만들어야겠죠?

 

현재 날짜 및 시간으로 txt 파일을 생성하는 스크립트를 만들어봤어요.

 

 

이 스크립트를 /Users/philip/scripts 폴더 안에 넣어줄게요.

 

[참고]
launchctl은 WorkingDirectory라고 해서, launchctl을 사용할 수 있는 디렉토리가 정해져있어요. 
그래서 script 위치는 Users 디렉토리 내부 경로로 설정해 주시는 것이 좋습니다.

 

 

그다음 launchctl에 등록할 정보를 담은 plist 파일을 만들어줄게요.

 

보통 plist 파일의 이름은 reverse domain 형태로 많이 하기 때문에, 이름은 com.philip.test.launchctl.plist 라고 지어줄게요.

 

 

plist 설정값들의 의미를 간단하게 살펴봅시다.

  • Label: launchctl에 등록할 프로세스의 고유한 명칭(?)
  • ProgramArguments: 프로그램 실행에 필요한 인자
  • StartInterval: 몇 초 간격으로 프로그램을 실행시킬지 (단위는 second)
  • RunAtLoad: launchctl에 등록(load)되는 시점에 프로그램을 실행시킬지 여부
  • StandardErrorPath: 에러로그를 저장할 경로
  • StandardOutPath: 프로그램이 출력하는 로그를 저장할 경로
  • WorkingDirectory: 프로세스가 위치할 경로 (cd 명령어라고 보면 될 듯?)

 

 

즉, 제가 생성한 com.philip.test.launchctl.plist 파일 정보를 쉬운 말로 해석해 보면 아래와 같습니다.

com.philip.test.launchctl 이란 이름(Label)으로 launchctl에 프로세스를 등록할 거야.

그 프로세스는 /Users/philip/scripts/ 경로(WorkingDirectory)로 이동해서 sh script.sh 명령어(ProgramArguments)를 실행시키는 거야.

launchctl에 등록하자마자 프로그램을 실행시켜 주고(RunAtLoad), 그 이후 5초마다 반복(StartInterval)해서 실행시켜 줘.

에러가 발생하면 ../error/error.log (StandardErrorPath)라는 이름으로 저장해 주고, 프로그램 로그는 ../output/out.log (StandardOutPath)라는 이름으로 저장해 줘.

 

 

 

이제 위에서 생성한 plist 파일을 ~/Library/LaunchAgents 안에 넣어주세요.

 

그다음 터미널에서 아래 명령어를 입력해 주세요.

 

$ launchctl load -w ~/Library/LaunchAgents/com.philip.test.launchctl.plist

 

 

끝이에요!! 이후부턴 자동으로 30초마다 스크립트가 잘 실행됩니다!!ㅎㅎㅎ

 

 

 

 

 

# launchctl에 등록한 프로세스를 해제하고 싶을 때

더 이상 자동으로 프로그램을 실행시킬 필요가 없을 땐, 터미널에 아래 명령어를 입력해서 프로세스를 제거해 주시면 됩니다.

 

$ launchctl unload -w ~/Library/LaunchAgents/com.philip.test.launchctl.plist

 

 

 

# launchctl에 문제없이 잘 등록되었는지 확인하는 방법

launchctl load 명령어를 사용하면, 문제가 있어도 별다른 로그가 안 나오기 때문에 잘 등록되었는지 알 수가 없어요.

 

이땐 아래 명령어를 사용해서 현재 프로세스 상태가 0인지 확인해 주세요.

 

$ launchctl list | grep com.philip.test.launchctl 

 

 

 

만약 문제가 있다면, 0이 아니라 아래처럼 다른 상태값이 나오게 됩니다.

 

 

 

 

# python3 스크립트 실행시키는 방법?

자동으로 프로그램 실행시킬 수 있는 건 shell script 뿐이 아니겠죠.

 

python3(또는 python) 스크립트를 실행시키고 싶으면 plist 파일의 ProgramArguments를 아래처럼 작성해 주시면 됩니다.

 

 

 

 

 

실행시킬 python3의 경로를 직접 설정하고 싶으면 아래 명령어로 python3의 경로를 얻어온 뒤,

 

$ which python3

 

 

 

ProgramArguments에 넣어주시면 됩니다^^

 

 

 

 

# 스크립트 실행에 필요한 argument 설정방법

Array 타입인 ProgramArguments에 필요한 argument를 추가해 주면 됩니다.

 

예를 들어서, 아래처럼 ProgramArguments에 'hello'랑 'world' 문자열을 배열에 추가하면, 

 

 

 

반복적으로 아래 명령어가 실행됩니다.

 

$ sh script.sh 'hello' 'world'

 

 

 

# 특정 시간에 프로그램을 실행시키고 싶으면?

plist 파일의 StartInterval 대신 StartCalendarInterval 속성을 사용하면, 특정 시간마다 프로그램을 실행시킬 수 있습니다.

 

 

정각마다 프로그램을 실행시키고 싶으면 아래처럼 설정해 주세요.

 

 

 

매일 00시 정각마다 프로그램을 실행시키고 싶으면 Hour 설정도 추가하면 됩니다.

 

[참고]
프로그램을 launchctl에 load 하는 시점은 정각이 아닐 수 있기 때문에 RunAtLoad을 false로 설정해 줬습니다.

 

 

# TroubleShooting

## Status = 78 인 경우

1) 스크립트의 경로가 가능한 WorkingDirectory인지 확인.
  - Desktop에 위치하고 있다면 스크립트를 /Users/<username>/ 로 경로 이동.
2) plist 파일에 입력한 정보가 올바른지 확인.
  - ex) 파일명은 올바른지, 실행할 프로그램 이름은 올바른지

 

 

## 그 외의 경우

StandardErrorPath 경로의 에러로그를 확인해 주세요.

 

추가로, 터미널에 아래 명령어를 입력하면 에러코드에 대한 간략한 description을 볼 수 있습니다.

 

$ launchctl error {상태값}

 

 

 

 

# 참고

- https://ss64.com/osx/launchctl.html

 

launchctl Man Page - macOS - SS64.com

Interfaces with launchd to load, unload daemons/agents and generally control launchd. launchctl supports taking subcommands on the command line, interactively or even redirected from standard input. ~/Library/LaunchAgents  Per-user agents provided by the

ss64.com

 


이번 글은 여기서 마무리.

 

 

 

반응형