백그라운드 프로세스 관리¶
POSIX 계열 셸과 systemd를 사용하는 Linux에서 장기 실행 명령을 세션과 분리하는 방법입니다. 대화형 작업은 tmux/screen, 일회성 배치는 nohup, 지속 서비스는 systemd를 기준으로 합니다.
적용 범위와 전제
셸의 job-control 및 huponexit, SSH 서버, systemd-logind 정책에 따라 세션 종료 시 신호와 프로세스 생존 여부가 달라집니다. 컨테이너나 배치 스케줄러에서는 해당 런타임의 수명주기 기능을 우선 사용하세요.
개요¶
터미널 연결이 끊기면 셸이나 터미널이 작업에 SIGHUP을 보낼 수 있지만, 실제 동작은 셸 옵션과 프로세스의 신호 처리 방식에 좌우됩니다. 장기 실행 작업은 표준 입출력, 재시작 정책, 종료 상태를 세션 밖에서 관리해야 합니다.
graph TD
A[프로세스 실행] --> B{세션 유지 필요?}
B -->|예| C[screen/tmux 사용]
B -->|아니오| D{신규 프로세스?}
D -->|예| E[nohup으로 시작]
D -->|아니오| F[disown으로 분리]
C --> G[세션 분리/재연결 가능]
E --> H[백그라운드 실행]
F --> H
style C fill:#e8f5e8
style E fill:#fff3e0
style F fill:#fff3e0
프로세스 제어 명령어¶
기본 작업 제어¶
| 명령어 | 단축키 | 설명 |
|---|---|---|
Ctrl+Z |
- | 현재 프로세스 일시 중지 (SIGTSTP) |
bg |
- | 중지된 프로세스를 백그라운드에서 재개 |
fg |
- | 백그라운드 프로세스를 포어그라운드로 이동 |
jobs |
- | 현재 셸의 작업 목록 표시 |
disown |
- | 셸에서 작업 분리 |
프로세스 상태 흐름¶
stateDiagram-v2
[*] --> Running: 프로세스 시작
Running --> Stopped: Ctrl+Z
Stopped --> Running: fg
Stopped --> Background: bg
Background --> Running: fg
Background --> Detached: disown
Detached --> [*]: 세션 종료 후에도 실행
Running --> [*]: 완료/종료
실행 중인 프로세스 백그라운드 전환¶
이미 실행 중인 프로세스를 세션과 분리하는 방법:
방법 1: disown 사용¶
# 1. 실행 중인 프로세스 일시 중지
Ctrl+Z
# 2. 작업 번호 확인
jobs
# [1]+ Stopped python long_running_script.py
# 3. 백그라운드로 전환
bg %1
# 4. 셸에서 분리 (SIGHUP 무시)
disown -h %1
disown 옵션
disown: 작업을 작업 테이블에서 제거disown -h: 작업을 유지하되 SIGHUP 무시disown -a: 모든 작업에 대해 적용
방법 2: reptyr로 프로세스 마이그레이션¶
실행 중인 프로세스를 다른 터미널(screen/tmux)로 이동:
# reptyr 설치
sudo apt install reptyr
# 프로세스 PID 확인
ps aux | grep process_name
# 새 터미널/screen 세션에서
reptyr <PID>
새 프로세스 시작 방법¶
nohup 명령어¶
nohup은 프로세스가 SIGHUP 신호를 무시하도록 합니다:
nohup 동작 원리¶
sequenceDiagram
participant User as 사용자
participant Shell as 셸
participant nohup as nohup
participant Process as 프로세스
User->>Shell: nohup command &
Shell->>nohup: 프로세스 생성
nohup->>Process: SIGHUP 핸들러 설정
nohup->>Process: stdin 닫기
nohup->>Process: stdout/stderr → nohup.out
Shell->>User: PID 반환
User->>Shell: exit
Shell--xProcess: SIGHUP (무시됨)
Process->>Process: 계속 실행
setsid 명령어¶
새 세션을 생성하여 프로세스를 완전히 분리:
# 새 세션에서 명령 실행
setsid command > output.log 2>&1
# nohup과 결합
setsid nohup command > output.log 2>&1 &
터미널 멀티플렉서¶
tmux¶
tmux는 세션 관리와 창 분할 기능을 제공합니다:
# 새 세션 시작
tmux new -s session_name
# 세션 분리
Ctrl+B, D
# 세션 목록 확인
tmux ls
# 세션 재연결
tmux attach -t session_name
# 특정 명령으로 세션 시작
tmux new -d -s backup "rsync -avz /src /dest"
tmux 주요 단축키¶
| 단축키 | 기능 |
|---|---|
Ctrl+B, D |
세션 분리 |
Ctrl+B, C |
새 창 생성 |
Ctrl+B, N |
다음 창 |
Ctrl+B, P |
이전 창 |
Ctrl+B, % |
수평 분할 |
Ctrl+B, " |
수직 분할 |
Ctrl+B, [ |
스크롤 모드 |
screen¶
GNU Screen도 비슷한 기능을 제공합니다:
# 새 세션 시작
screen -S session_name
# 세션 분리
Ctrl+A, D
# 세션 목록 확인
screen -ls
# 세션 재연결
screen -r session_name
# 분리된 세션이 있을 때 강제 재연결
screen -dr session_name
systemd 서비스로 관리¶
재시작, 부팅 연동, 권한, 로그가 필요한 지속 서비스는 systemd 단위로 관리하는 편이 관측과 복구에 유리합니다:
# /etc/systemd/system/myapp.service
[Unit]
Description=My Application
After=network.target
[Service]
Type=simple
User=appuser
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/run.sh
Restart=on-failure
RestartSec=10
# 로그 설정
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
# 서비스 시작
sudo systemctl start myapp
# 부팅 시 자동 시작
sudo systemctl enable myapp
# 상태 확인
sudo systemctl status myapp
# 로그 확인
journalctl -u myapp -f
방법 비교¶
| 방법 | 장점 | 단점 | 사용 사례 |
|---|---|---|---|
| nohup | 간단함, 추가 설치 불필요 | 출력 확인 어려움 | 일회성 장기 작업 |
| disown | 실행 중 프로세스에 적용 가능 | stdin/stdout 관리 필요 | 긴급한 세션 분리 |
| tmux/screen | 출력 확인, 재연결 가능 | 추가 학습 필요 | 대화형 작업, 모니터링 |
| systemd | 자동 재시작, 로깅, 의존성 | 설정 복잡 | 프로덕션 서비스 |
실전 예제¶
백업 스크립트 실행¶
# tmux 세션에서 백업 실행
tmux new -d -s backup "bash /opt/scripts/backup.sh >> /var/log/backup.log 2>&1"
# 진행 상황 확인
tmux attach -t backup
# 또는 nohup 사용
nohup /opt/scripts/backup.sh >> /var/log/backup.log 2>&1 &
echo "Backup started with PID: $!"
Python 스크립트 백그라운드 실행¶
# 가상환경과 함께 사용
nohup /opt/venv/bin/python /opt/app/main.py > /var/log/app.log 2>&1 &
# PID 파일 생성
nohup python main.py > app.log 2>&1 & echo $! > app.pid
실행 중인 프로세스 안전하게 분리¶
#!/bin/bash
# save_process.sh - 실행 중인 프로세스를 안전하게 백그라운드로 전환
# 1. 현재 작업 저장
jobs -l
# 2. 모든 작업을 백그라운드로
for job in $(jobs -p); do
disown -h $job
echo "Detached PID: $job"
done
# 3. 확인
ps aux | grep "your_process"
주의사항¶
리소스 모니터링
백그라운드 프로세스도 시스템 리소스를 사용합니다. 정기적으로 확인하세요:
완료 및 실패 판정¶
echo $!, disown, systemctl start의 성공은 작업 완료 증거가 아닙니다. 일회성 작업은 종료 코드와 예상 산출물의 크기·체크섬을 확인하고, 서비스는 systemctl show myapp -p Result -p ExecMainStatus와 journal을 확인합니다. 자동 재시도는 영구 오류를 반복할 수 있으므로 시작 제한, 알림, 부분 산출물 정리 또는 멱등성을 함께 정의합니다.