리눅스 크론탭 기본(Basic of crontab)

Crontab !?

유닉스 계열의 시간기반 잡 스케줄러이다. 서버를 운영하다 보면 관리의 편의성을 위해 쉘 스크립트를 일정한 주기로 실행하는 등의 고정된 작업을 필요로할때가 있다. 주로 로그를 남기기 위해 사용하는 듯 싶고 나의 경우 운영하고 있는 서비스때문에 주기적으로 크롤링을 해야돼서 크론탭을 이용하고있다.

작업을 고정된 시간, 날짜, 간격에 주기적으로 실행할 수 있도록 스케줄링하기 위해 사용한다
각각의 사용자들은 개인별로 자신들만의 crontab을 가질 수 있으며 관리자가 직접 작업들을 공통으로 지정하기도 한다.

파일 위치

/etc/crontab

주로 시스템 관련 작업들을 등록할때 사용하는 경로이다.

/var/spool/cron

시스템 개별사용자들이 등록해놓은 crontab이 위치해있는 경로이다. 일반적으로 root계정용 하나와 각 계정당 1개의 파일을 가진다.

사용법

기본 형태와 예시를 살펴보자.

1
2
3
4
5
6
7
8
9
10
# crontab -e

# ┌───────────── min (0 - 59)
# │ ┌────────────── hour (0 - 23)
# │ │ ┌─────────────── day of month (1 - 31)
# │ │ │ ┌──────────────── month (1 - 12)
# │ │ │ │ ┌───────────────── day of week (0 - 6) (0 to 6 are Sunday to Saturday, or use names; 7 is Sunday, the same as 0)
# │ │ │ │ │
# │ │ │ │ │
# * * * * * command to execute

예시

1
2
3
4
5
# 매일 20시 (오후 8시)에 export_dump.sh라는 쉘 프로그램을 실행
0 20 * * * /home/oracle/scripts/export_dump.sh

# 매주 일요일 0시 1분에 for_crawling.sh 쉘 프로그램을 실행
0 1 * * 0 /home/test_user/scripts/for_crawling.sh

관련명령어

  • 예약작업 생성 및 수정

    1
    crontab -e
  • 예약된 작업 삭제

    1
    crontab -r
  • crontab 작업 리스트 출력

    1
    crontab -l
  • 시스템 사용자의 crontab 편집

    1
    crontab -u <user_name>

    root 사용자는 개인 사용자의 crontab을 수정하거나 삭제할 수 있다.

  • 크론탭 재시작

    1
    service crond restart

    크론탭을 생성하거나 수정했다면 혹시모르니 꼭 재시작을 해주자!!

간단한 쉘 스크립트를 주기적으로 실행하기위해 이용했던 crontab은 큰 무리없이 지금까지 사용해왔다. 하지만 코드를 조금 변경하면서 파이썬 스크립트를 추가하면서 문제가 발생했고 해결과정을 정리하고자 한다.

crontab 사용시 주의점!!

crontab의 규칙에 맞게 설정을 했음에도 불구하고 동작하는 않은 경우가 발생했다. 인터넷을 찾아보니 두세가지 정도의 이유가 있었다.

1. 환경변수

크론탭은 네 가지 환경변수를 가지고 있다. => SHELL / PATH / MAILTO / HOME

  • SHELL
    등록된 작업을 실행시킨 쉘을 지정한다(크론탭은 실행시에 별도로 쉘을 띄운다). 지정하지 않을시 기본값으로 /bin/sh로 지정된다.

  • PATH
    쉘을 별도로 띄워서 실행하는 특성때문에, 쉘에서 프로그램을 찾기위한 PATH도 별도로 지정해줄 필요가 있다. 로그인해서 쉘을 실행시키는 것이 아니기 때문에 PATH변수를 이용할 수 없기 때문이다.

  • MATILTO
    (크게 중요하진 않은것 같다)크론이 수행한 결과를 메일로 보내준다. 기본값으로 작업을 실행한 주체에게 전송하게 되어있다.

  • HOME
    crontab의 home 디렉토리(:12)경로를 설정한다. 기본적으로는 crontab의 실행유저의 홈디렉토리로 /etc/passwd에 설정된 경로를 따른다.

예시

1
2
3
4
5
6
# crontab -e

SHELL=/usr/bin/zsh
PATH=/sbin:/bin:/usr/sbin:/usr/bin

* * * * * sample.sh

매분마다 sample.sh을 실행하며 프로그램이 작동할 쉘과 경로를 지정해주었다.

2. 권한문제

크론탭을 설정하는 방법에는 crontab -e 명령어를 통한 작성과 직접 /etc/crontab을 편집하는 두 가지 방법이 있다. 두 번째 방법처럼 vi /etc/crontab을 통해 직접 수정을 했을 경우 root 권한 명령을 실행하려면 root권한을 명시해 주어야 한다.

1
2
3
4
5
# crontab -e
* * * * * example.sh

# vi /etc/crontab
* * * * * root example.sh

두 번째 처럼 root 권한을 명시해야 한다!!

3. 절대경로 / 상대경로

절대경로로 작성하는 것을 추천한다 @.@

4. 최소 반복 시간

크론탭의 최소 반복시간은 1분이다. 명심하자.


내가 겪은 문제

파이썬으로 웹 페이지를 크롤링하는 코드를 작성하였고 간단한 설명을 위해 한글로 주석을 달아놓았다. 또한 virtualenv를 사용하고 있었기 때문에 크론이 돌아가는 쉘이 가상환경 경로를 모르는 듯 했다.

약 두 세시간 삽질끝에 이유를 위와 같이 알 수 있었고 정석대로 해결을 못해서 한글주석을 지웠다… 그리고 path설정을 하니 정상작동했다.

  • path 설정
    파이썬 가상환경을 사용하고 있다면, 패키지들과 어떤 파이썬으로 실행되는지 path로 설정해줄 필요가 있다고 한다. 그래서 구동되는 파이썬의 path를 보기위해 다음과 같이 했다.

    1
    2
    3
    4
    python3 # 파이썬 실행

    >>> import sys # sys모듈 임포트
    >>> sys.path # path 출력(리스트 형태)

    sys.path를 실행해서 출력된 path값들을 crontab의 PATH에 추가해 주었다.

  • 가상환경 경로 입력
    스크립트를 실행하는 명령을 입력하기 전에 파이썬 가상환경을 활성화하는 명령을 입력해 보았다.

    1
    2
    3
    # crontab -e

    * * * * * source /path/to/virtualenv/bin/activate && python3 /path/to/file/example.py

    위와 같이 했더니 가상환경을 정상적으로 활성화하고 파이썬 스크립트를 실행했다.

  • 파이썬 경로 입력
    파이썬 인터프리터에게 어떤 파이썬을 사용할 지 알려주는 것이다.

    1
    #!/home/my/virtualenv/bin/python

    스크립트 맨위에 주석을 달아준다.

  • SHELL 경로 지정
    주로 zsh을 설치하여 사용하고 있기 때문에 경로를 바꿔보았다

    1
    2
    # crontab -e
    SHELL=/usr/bin/zsh

    이렇게 했더니 웬걸… python을 찾을 수 없다고 한다. 그래서 sys.path을 통해 파이썬 경로를 알아내어 PATH설정도 해주었는데 그래도 작동하지 않았다..

  • 한글주석 삭제
    한글주석을 지워보았더니 non-ascii 문제가 사라졌다. 그 다음에 path설정을 해주었더니 올바르게 동작…


추가 팁?

귀차니즘으로 인해 아직 해보지는 않았지만 실행할 명령어를 크론탭에서 바로 작성하는 것이 아니라 따로 .sh을 만들고 크론에서 그 .sh을 실행하는 방법이다. 왜 이렇게하면 잘 작동하는 가에 대한 이유를 찾아보려고 했으나 아직까진 발견하지 못했다.

1
2
3
4
5
# vi example.sh
python /path/to/test.py

# crontab -e
* * * * * /path/example.sh

바로 파이썬 스크립트를 입력하지 말고 한번 .sh로 감싼다음에 그 .sh 스크립트를 실행한다는 것이다. 꼭 한번 시도해보자.

Share