Development note/Linux

[CentOS] Linux에서 프로그램을 백그라운드에서 실행하는 방법과 서비스 등록 방법

v명월v 2020. 5. 21. 12:51

안녕하세요. 명월입니다.


이 글은 Linux에서 프로그램을 백그라운드에서 실행하는 방법과 서비스 등록 방법에 대한 글입니다.


우리가 자주 사용하는 윈도우에서 프로그램을 백그라운드에서 실행하는 방법은 단순히 콘솔화면이나 윈도우 폼을 없애고 프로그램을 실행하는 것만으로 가능합니다.

그러나 리눅스 환경에서는 기본적으로 콘솔에서 커맨드 환경이기 때문에 프로그램을 실행하는 것만으로 백그라운드에 실행되는 게 아니고 실행하는 파일 끝에 &를 추가함으로 백그라운드에서 실행하는 것이 가능합니다.

프로그램을 실행할 예제 프로그램을 작성하겠습니다.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <chrono>
#include <thread>
using namespace std;
// 실행 함수
int main() {
  // 쓰레드
  thread th([]() -> void {
    // 무한 루프
    while (true) {
      // 현재 시간
      time_t timec = time(NULL);
      // 현재 시간
      struct tm* pLocal = localtime(&timec);
      // yyyy-mm-dd hh:mm:ss 포멧 설정
      char buffer[1024];
      sprintf(buffer, "%04d-%02d-%02d %02d:%02d:%02d",
        pLocal->tm_year + 1900, pLocal->tm_mon + 1, pLocal->tm_mday,
        pLocal->tm_hour, pLocal->tm_min, pLocal->tm_sec);
      
      // 파일 스트림 생성
      ofstream ostream;
      // 파일 열기, 옵션은 기존에 있으면 아래에 내용 추가
      ostream.open("/home/work/new.txt", ios_base::app);
      // 파일에 현재 날짜 시간 작성
      ostream << buffer << endl;
      // 콘솔 출력 (생략)
      // cout << buffer << endl;
      // 파일 스트림 닫기
      ostream.close();
      // 1초 단위
      this_thread::sleep_for(chrono::seconds(1));
    }
  });
  // 쓰레드가 끝날 때까지 기다린다.
  // 무한 루프라 Ctrl + C를 누르지 않는 이상 종료 안됨
  th.join();
  return 0;
}

위 소스는 아주 간단한 소스입니다. 단순히 파일에 현재 날짜를 계속 넣는 것입니다.

일단 컴파일해서 그냥 실행 해보겠습니다.

컴파일 후 실행하면 무한 루프이기 때문에 프로그램이 종료하지 않습니다. Ctrl + C를 눌러서 종료하고 생성된 파일을 확인하겠습니다.

파일에 현재 시간이 일초 단위로 작성되는게 확인이 됩니다.

이제 이걸 그냥 실행하는 것이 아니고 백그라운드에서 실행하겠습니다.

그냥 실행하는 명령어에 뒤에 & 표시만 붙이면 백그라운드에서 실행됩니다.

ps로 프로세스 확인하니 확실히 기동 중이고 파일도 1초 단위로 시간이 작성되는 것을 확인할 수 있습니다.


이제 이 프로세스를 중지해야 하겠습니다. 프로세스로 돌기 때문에 그냥 Ctrl + C를 누른다고 중지되진 않습니다.

ps로 확인하니 pid가 15631로 확인이 됩니다.

그대로 kill -9 15631하면 프로세스는 종료됩니다.

이제 이걸 제가 Linux에 부팅할 때 자동으로 실행하고 싶습니다.

방법은 두가지입니다만, 부팅시 실행되는 스크립트에 실행시키는 방법과 부팅 데몬으로 통해서 실행하는 방법입니다.


첫번째 부팅시 실행되는 스크립트는 /etc/rc.d 폴더에 있습니다.

이 스크립트는 init.d부터 rc0.d, ... rc.local 순으로 실행됩니다. 예제 프로그램은 따로 단계의 절차가 필요한 건 아니니 그냥 가장 아래의 rc.local에 실행 명령어를 입력하면 부팅하면 자동 실행합니다.

재부팅을 하니 test 프로그램이 자동으로 실행된 것을 확인할 수 있습니다. 위의 sudo가 붙어있는 건 rc.local에서 실행한 명령어로 실제 프로세스는 두번째입니다.

(참고로 재부팅을 해도 실행이 안 되는 경우가 있는데, rc.local이 실행 권한이 없어서 일 경우가 많습니다. chmod +x rc.local로 권한을 추가합니다.)

이게 가장 쉬운 방법이고, 조금 고급지게 하는 방법은 서비스 데몬에 실행하는 방법입니다.

이번에는 /etc/rc.d/init.d 폴더로 이동합니다.


여기서 스크립트를 하나 생성하겠습니다.

#!/bin/bash
# test
# chkconfig: 5 50 50
# description: test
#
# service에 등록을 위해서는 chkconfig와 description 있어야 한다. 없으면 등록이 안된다.
# 먼저 앞의 5는 rc0.d부터 rc6.d에 동록하는 순번인데. 다른 순서가 필요한 프로세스 등록이면 이 순서에 맞추어서 등록하는 것이다. 
# test 프로세스는 그런거 필요없으니 적당히 5로..
# 50은 그 안에서 몇번째로 실행할 것인지 정하는 순서인데.. 이것도 적당히 50, 50으로 설정한다.
#
case $1 in
  start) # 파라미터가 start일 경우 service test start
    # 실행 중인 프로세스가 있는지 확인
    count=`ps -ef | grep '/home/work/test' | grep -v grep | wc -l`
    # 없으면
    if [ $count -eq 0 ]; then
      # 실행
      sudo /home/work/test &
    fi
  ;;
  stop) # 파라미터가 stop일 경우 service test stop
    # 실행 중인 프로세스 pid를 취득
    pid=`ps -ef | grep test | awk '{print $2}'`
    # kill
    kill -9 $pid
  ;;
esac
exit 0

등록이 되었으면 권한을 주고 데몬에 추가합니다.

chmod 755 test
chkconfig --add test
chkconfig --list test

등록이 되었습니다. 재부팅으로 확인해 보면 프로세스가 등록되어 있는 것을 확인할 수 있습니다.

여기까지 Linux에서 프로그램을 백그라운드에서 실행하는 방법과 서비스 등록 방법에 대한 글이었습니다.


궁금한 점이나 잘못된 점이 있으면 댓글 부탁드립니다.