터미널에서 오래 걸리는 명령을 실행할 때는 먼저 원하는 결과를 구분해야 한다. 잠시 다른 명령을 쓰려는지, 로그아웃 뒤에도 비대화형 작업을 남기려는지, 나중에 같은 대화형 화면으로 돌아오려는지에 따라 도구가 달라진다.
&, jobs, nohup, tmux는 모두 “백그라운드 실행”으로 묶이기 쉽지만 해결하는 문제가 다르다.
셸 job control은 현재 터미널 안의 작업을 다룬다
Bash의 job control은 한 셸 세션에서 실행한 파이프라인을 foreground와 background로 옮기는 기능이다.
sleep 600
# Ctrl-Z
jobs -l
bg %1
fg %1
터미널에서 Ctrl-Z를 누르면 보통 foreground 작업의 프로세스 그룹에 SIGTSTP가 전달된다. 프로세스가 이를 처리하는 방식에 따라 실제로 멈추지 않을 수도 있다. bg %1은 중지된 job을 background에서 계속 실행하고, fg %1은 다시 foreground로 가져온다.
Ctrl-C도 “프로세스를 무조건 종료하는 키”가 아니다. 터미널 드라이버가 foreground 프로세스 그룹에 보통 SIGINT를 전달하고, 프로그램이 기본 동작을 따를 때 종료되는 것이다. 프로그램은 신호를 처리하거나 무시할 수 있다.
처음부터 background로 실행하려면 명령 끝에 &를 붙인다.
long-command >run.log 2>&1 &
jobs -l
이 방식은 현재 셸에서 다른 명령을 입력할 수 있게 할 뿐, 로그아웃 이후 생존과 재시작을 보장하는 서비스 관리 기능은 아니다.
nohup은 SIGHUP 처리를 바꾸지만 서비스 관리자는 아니다
nohup은 지정한 명령이 SIGHUP을 무시하도록 준비하고 실행한다. 스스로 background로 보내지는 않으므로 &와 출력 리다이렉션을 함께 쓰는 경우가 많다.
nohup long-command >run.log 2>&1 &
로그 파일을 명시하면 기본 nohup.out에 출력이 섞이는 일을 피할 수 있다. 다만 이 명령에는 다음 기능이 없다.
- 실패한 프로세스 자동 재시작
- 부팅 뒤 자동 시작
- 의존 서비스와 시작 순서 관리
- 리소스 제한과 일관된 로그 수집
- 정상 종료 시간과 권한 정책 관리
일회성 배치 작업을 로그아웃 뒤에도 끝내려는 목적에는 맞을 수 있다. 오래 운영할 서버 프로세스라면 systemd 같은 서비스 관리자나 작업 스케줄러, 컨테이너 오케스트레이터를 사용해야 한다.
Bash의 disown은 job을 셸의 job table에서 제거하거나, -h 옵션으로 셸이 보내는 SIGHUP의 대상에서 제외하도록 표시하는 내장 명령이다. 이것도 Bash job control의 상태를 바꾸는 기능이지 프로세스를 완전한 daemon으로 바꾸는 기능은 아니다.
tmux는 대화형 작업 화면을 다시 붙이기 위한 도구다
원격 서버에서 편집기나 모니터링 화면, 여러 셸을 계속 사용해야 한다면 tmux가 잘 맞는다.
tmux new-session -s work
# 작업 중 Ctrl-b d 로 detach
tmux list-sessions
tmux attach-session -t work
클라이언트를 detach해도 tmux 서버와 세션 안의 프로그램은 계속 실행된다. SSH 연결이 끊긴 뒤 다시 접속해 같은 화면에 attach할 수 있다는 점이 nohup과 다르다.
그러나 tmux도 호스트가 재부팅되거나 tmux 서버가 끝나면 세션을 보존하지 못한다. 프로세스 재시작과 상태 복구가 필요한 서비스라면 여전히 서비스 관리 도구가 필요하다. 비대화형 명령 하나만 남기는 데 tmux를 필수로 쓸 이유도 없다.
상황별로 고르면 도구가 단순해진다
| 원하는 결과 | 알맞은 출발점 | 주의할 점 |
|---|---|---|
| 현재 셸에서 잠시 다른 명령 실행 | &, jobs, bg, fg |
로그아웃 생존을 보장하지 않음 |
| 일회성 비대화형 명령을 로그아웃 뒤까지 실행 | nohup과 명시적 리다이렉션 |
재시작·상태 관리 없음 |
| 원격 대화형 화면에 다시 접속 | tmux |
호스트·tmux 서버 종료에는 취약 |
| 장기 서비스 운영 | systemd 등 서비스 관리자 | 단위 파일, 권한, 재시작 정책 설계 필요 |
| 정해진 시각의 반복 작업 | timer·scheduler | 중복 실행과 실패 알림 설계 필요 |
어떤 도구를 쓰든 PID만 보고 프로세스가 건강하다고 판단하지 않는다. 출력 로그, 종료 코드, 작업 결과와 필요한 경우 애플리케이션 수준 상태를 함께 확인한다.
SSH 설정은 반복 입력을 줄이되 비밀을 넣지 않는다
자주 접속하는 호스트는 ~/.ssh/config에 별칭을 둘 수 있다.
Host app-jump
HostName jump.example.com
User ops
IdentityFile ~/.ssh/id_ed25519_app
IdentitiesOnly yes
이후 ssh app-jump처럼 접속한다. 설정 파일에는 호스트와 사용자 같은 민감할 수 있는 인프라 정보가 들어갈 수 있으므로 공개 dotfiles 저장소에 그대로 올리지 않는다. 개인 키는 어떤 Git 저장소에도 커밋하지 않는다.
처음 보는 호스트 키를 자동으로 무시하거나 기존 known_hosts 항목을 근거 없이 지우지 않는다. 호스트 키가 바뀌었다면 서버 재설치인지, DNS·접속 대상이 달라졌는지, 중간자 공격 가능성이 있는지 신뢰할 수 있는 경로로 확인해야 한다. SSH 보안의 기본 흐름은 SSH 1과 2의 차이 및 보안에서 이어서 볼 수 있다.
포트 포워딩은 방향과 바인딩 주소를 함께 본다
로컬 포워딩은 로컬 포트로 들어온 연결을 SSH 서버 쪽에서 목적지로 이어 준다.
ssh -N \
-L 127.0.0.1:15432:db.internal:5432 \
-o ExitOnForwardFailure=yes \
app-jump
이 예에서 로컬 애플리케이션은 127.0.0.1:15432에 접속하고, SSH 연결의 원격 쪽이 db.internal:5432로 연결한다. 127.0.0.1을 명시하면 포워딩 포트가 로컬 호스트에서만 열리도록 의도를 드러낼 수 있다.
-L: 로컬에 듣는 포트를 열고 원격 쪽 목적지로 전달-R: 원격에 듣는 포트를 열고 로컬 쪽 목적지로 전달-D: 로컬 동적 SOCKS 프록시를 생성-N: 원격 셸이나 명령을 실행하지 않고 포워딩에 집중
빈 바인딩 주소나 *를 사용하면 다른 인터페이스에 노출될 수 있다. 원격 포워딩은 서버의 GatewayPorts 설정에도 영향을 받는다. 터널은 전송 경로를 암호화할 뿐, 목적지 서비스의 인증과 접근 제어를 대신하지 않는다.
연결 자체가 불안정할 때는 네트워크 문제 해결 명령어처럼 DNS, 경로, 포트, SSH 인증을 단계별로 분리해 확인하는 편이 빠르다.
참고 자료
'배움과 성장 > DevOps·클라우드' 카테고리의 다른 글
| GitOps란 무엇인가: OpenGitOps 4원칙과 CI/CD 차이 (0) | 2025.10.18 |
|---|---|
| 빌드 시스템·의존성 관리·CI: 메타프로그래밍 강의 핵심 정리 (0) | 2025.09.08 |
| grep 명령어 실전 가이드: 로그 검색부터 정규식·스크립트까지 (2) | 2025.06.03 |
| DevOps·SRE 지표 설계: 역할별 숫자보다 Delivery·Reliability 결과 보기 (0) | 2025.03.08 |
| Kubernetes Spot 중단 대응: 단일 Pod 무중단이 불가능한 이유 (0) | 2024.09.20 |
댓글