리눅스 tmux 사용법 - 세션 유지, 창 분할, 스크립트 제어까지
이 명령어를 언제 쓰는가
운영 서버에서 두 시간짜리 인덱스 재생성을 돌리는 중에 노트북을 덮어야 할 때, 장애 대응 중에 로그 창·모니터링 창·명령 창을 동시에 띄워 놓고 오가야 할 때, 여러 대의 서버에 같은 명령을 동시에 쳐야 할 때 tmux를 쓴다.
tmux는 터미널 멀티플렉서다. 서버 안에 터미널 세션을 만들어 두고, 사용자는 거기에 붙었다 떼었다 한다. SSH가 끊겨도 세션은 서버에서 계속 돌아간다. 다시 접속해 tmux attach 한 줄이면 끊기기 직전 화면이 스크롤백까지 그대로 돌아온다.
같은 일을 하는 screen이 먼저 있었지만, 지금 새로 배운다면 tmux 쪽이다. 창 분할이 자연스럽고, 설정 문법이 일관되며, 무엇보다 바깥에서 명령으로 세션을 조종할 수 있어 자동화에 쓸 수 있다. RHEL 8부터 Red Hat은 screen을 deprecated로 두고 tmux를 표준으로 삼았다.
세 층의 구조
tmux를 이해하는 데 필요한 것은 이 구조 하나다.
- 세션(session) — 붙었다 뗄 수 있는 가장 바깥 단위. 작업 하나에 세션 하나로 잡는다.
- 윈도우(window) — 세션 안의 탭. 브라우저 탭이라고 생각하면 된다. 한 번에 하나만 보인다.
- 페인(pane) — 윈도우를 세로·가로로 쪼갠 화면. 동시에 여러 개가 보인다.
예를 들어 deploy 세션 안에 build, logs, db 세 윈도우를 두고, logs 윈도우는 좌우 두 페인으로 나눠 각각 다른 로그를 tail -f 하는 식으로 쓴다.
기본 형식
tmux new -s 세션이름 # 새 세션 만들고 들어가기
Ctrl+b 다음에 d # 세션에서 빠져나오기(분리)
tmux ls # 세션 목록
tmux attach -t 세션이름 # 다시 붙기
Ctrl+b가 프리픽스 키다. Ctrl+b를 누르고 손을 뗀 뒤 이어서 명령 키를 누른다. 동시에 누르는 것이 아니다. 아래에서 Ctrl+b → d로 표기한 것은 모두 이 방식이다.
자주 쓰는 명령과 키
| 명령·키 | 의미 | 비고 |
|---|---|---|
tmux new -s 이름 | 이름 붙여 세션 시작 | 이름 없이 만들면 0, 1이 되어 구분이 어렵다 |
tmux ls | 세션 목록 | tmux list-sessions의 축약 |
tmux a -t 이름 | 세션에 다시 붙기 | attach의 축약. 세션이 하나면 tmux a |
tmux kill-session -t 이름 | 세션 종료 | 붙지 않고 밖에서 |
tmux new -d -s 이름 '명령' | 분리 상태로 바로 시작 | 스크립트·크론에서 쓴다 |
Ctrl+b → d | 분리(detach) | 가장 중요한 키 |
Ctrl+b → c | 새 윈도우 | |
Ctrl+b → 0~9 | 번호로 윈도우 이동 | |
Ctrl+b → , | 윈도우 이름 바꾸기 | 세 개 넘어가면 필수 |
Ctrl+b → % | 세로선으로 좌우 분할 | |
Ctrl+b → " | 가로선으로 상하 분할 | |
Ctrl+b → 방향키 | 페인 이동 | |
Ctrl+b → z | 현재 페인 확대·복귀 | 한 페인을 잠깐 크게 볼 때 |
Ctrl+b → [ | 복사·스크롤 모드 | 방향키·PgUp으로 스크롤, q로 나온다 |
Ctrl+b → ? | 키 바인딩 목록 |
실전 예제
1) 장시간 작업을 세션에 담고 자리를 뜬다. 가장 기본 흐름이다.
tmux new -s reindex
# 세션 안에서
psql -d shopdb -c 'REINDEX TABLE CONCURRENTLY orders;'
# 자리를 뜨려면 Ctrl+b 다음 d
나중에 다시 접속해서 확인한다.
tmux ls
reindex: 1 windows (created Tue Aug 25 22:32:44 2026)
tmux a -t reindex
2) 장애 대응용 화면을 한 번에 구성한다. 스크립트로 만들어 두면 사고가 났을 때 한 줄로 상황판이 뜬다.
#!/bin/bash
tmux new-session -d -s incident -n overview
tmux send-keys -t incident:overview 'top' Enter
tmux split-window -t incident:overview -h
tmux send-keys -t incident:overview 'tail -f /var/log/nginx/error.log' Enter
tmux split-window -t incident:overview -v
tmux send-keys -t incident:overview 'watch -n 1 "ss -s"' Enter
tmux new-window -t incident -n shell
tmux attach -t incident
3) 여러 서버에 같은 명령을 동시에 친다. 페인마다 다른 서버에 접속해 두고 입력을 동기화한다. 클러스터 노드 점검에 유용하다.
tmux new-session -d -s cluster
tmux send-keys -t cluster 'ssh web01' Enter
tmux split-window -t cluster -h ; tmux send-keys -t cluster 'ssh web02' Enter
tmux split-window -t cluster -v ; tmux send-keys -t cluster 'ssh web03' Enter
tmux select-layout -t cluster tiled
tmux setw -t cluster synchronize-panes on
tmux attach -t cluster
이제 한 번 친 명령이 세 서버에 모두 들어간다. 끄는 것을 잊지 마라. 확인 작업이 끝나면 Ctrl+b → : 다음 setw synchronize-panes off를 반드시 실행한다. 켜 둔 채로 파괴적인 명령을 치면 세 대가 동시에 당한다.
4) 크론이나 배포 스크립트에서 세션을 미리 띄운다. 붙지 않은 채로 돌려 두고 필요할 때만 들어가 본다.
tmux new-session -d -s batch '/opt/jobs/nightly.sh 2>&1 | tee /var/log/nightly.log; read -r'
끝에 read -r을 붙인 이유가 있다. 이게 없으면 스크립트가 끝나는 순간 세션이 사라져 결과 화면을 볼 수 없다. 입력 대기를 하나 남겨 두면 화면이 유지된다.
5) 붙지 않고 세션 화면 내용을 가져온다. tmux가 screen보다 나은 지점이다. 자동화에서 쓸 수 있다.
tmux capture-pane -p -t batch | tail -20
-p는 결과를 표준 출력으로 보낸다는 뜻이다. 모니터링 스크립트에서 세션 상태를 긁어 알림에 붙일 수 있다.
6) 설정을 손봐 실무에서 쓸 만하게 만든다. ~/.tmux.conf에 넣는다.
# 스크롤백을 넉넉히. 기본 2000줄은 부족하다
set -g history-limit 50000
# 마우스로 페인 선택·크기 조절·스크롤
set -g mouse on
# 윈도우 번호를 1부터. 키보드 배열과 맞다
set -g base-index 1
setw -g pane-base-index 1
# 상태줄에 호스트명과 시각
set -g status-right ' #H %Y-%m-%d %H:%M '
# 색이 깨지면
set -g default-terminal 'screen-256color'
# 설정 다시 읽기: Ctrl+b 다음 r
bind r source-file ~/.tmux.conf \; display '설정을 다시 읽었다'
수정 후에는 세션 안에서 Ctrl+b → : 다음 source-file ~/.tmux.conf를 실행하면 바로 반영된다.
함정과 주의점
tmux 세션은 재부팅을 넘기지 못한다. 서버가 재부팅되면 tmux 서버 프로세스와 그 안의 모든 프로세스가 사라진다. tmux에 띄웠으니 안전하다고 생각하고 상시 서비스를 넣어 두는 경우가 있는데, 커널 업데이트 재부팅 한 번에 조용히 죽는다. 계속 살아 있어야 하는 것은 systemd 유닛으로 등록한다. tmux는 사람이 붙었다 뗐다 하는 작업용이다.
중첩 tmux에서 프리픽스가 먹히지 않는다. 로컬에서 tmux를 쓰는데 SSH로 들어간 서버에서도 tmux를 띄우면, Ctrl+b를 바깥쪽 tmux가 먼저 가져간다. 안쪽 tmux에 프리픽스를 보내려면 Ctrl+b를 두 번 누른다. 자주 그런다면 로컬 쪽 프리픽스를 Ctrl+a로 바꿔 겹치지 않게 한다.
# 로컬 ~/.tmux.conf
unbind C-b
set -g prefix C-a
bind C-a send-prefix
재연결 후 에이전트 포워딩이 깨진다. 실무에서 가장 성가신 문제다. tmux 세션의 환경변수는 세션을 처음 만든 시점에 고정되는데, SSH_AUTH_SOCK은 SSH 접속마다 새 경로가 된다. 그래서 다시 붙은 세션에서 git push나 다른 서버 ssh가 갑자기 비밀번호를 묻거나 이렇게 실패한다.
Error connecting to agent: No such file or directory
즉석 해결은 세션 안에서 새 소켓을 잡아 주는 것이다.
eval "$(tmux show-env -s SSH_AUTH_SOCK)"
근본 해결은 ~/.ssh/rc나 셸 시작 스크립트에서 소켓을 고정 경로로 심볼릭 링크해 두고, tmux는 그 고정 경로만 보게 하는 것이다.
# ~/.bashrc
if [ -n "$SSH_AUTH_SOCK" ] && [ ! -L "$SSH_AUTH_SOCK" ]; then
ln -sf "$SSH_AUTH_SOCK" ~/.ssh/ssh_auth_sock
fi
export SSH_AUTH_SOCK=~/.ssh/ssh_auth_sock
버전에 따라 설정 문법이 다르다. tmux는 메이저 업데이트에서 옵션 이름을 정리한 이력이 있다. 2.1에서 마우스 관련 옵션 여러 개가 mouse 하나로 합쳐졌고, 2.9에서 status-bg·status-fg 같은 옵션이 status-style로 통합됐다. 인터넷에서 주워 온 .tmux.conf가 서버에서 unknown option을 뱉는 이유가 대개 이것이다. CentOS 7에는 tmux 1.8이, RHEL 8·9에는 2.7~3.2대가 올라가 있어 노트북(3.x)과 문법이 다를 수 있다. tmux -V로 버전을 먼저 확인하고, 설정 파일에 버전 분기를 두거나 서버용 설정을 따로 관리한다.
TERM 설정이 어긋나면 화면이 깨진다. default-terminal을 tmux-256color로 두면 색이 잘 나오지만, 오래된 서버에는 그 terminfo 항목이 없어 vi나 less가 이상하게 그려진다. 서버 상태를 모르겠으면 호환성이 넓은 screen-256color가 무난하다. infocmp tmux-256color로 존재 여부를 확인할 수 있다.
세션이 방치되어 쌓인다. tmux ls가 열 줄 넘게 나오는 서버가 흔하다. 각 세션이 셸과 자식 프로세스를 붙들고 있어 자원을 먹고, 어느 세션이 실제로 돌고 있는 작업인지 알 수 없어진다. 세션 이름을 작업 기준으로 짓고(reindex-20260825), 끝난 세션은 그 자리에서 닫는다. 한 번에 정리하려면 tmux kill-server인데, 돌고 있는 작업까지 전부 죽으므로 목록을 확인한 뒤에만 쓴다.
nohup · screen · tmux 중 무엇을 쓸까
| 상황 | 선택 | 이유 |
|---|---|---|
| 결과를 로그로만 확인하는 단방향 배치 | nohup | 세션을 띄울 이유가 없다. 가장 가볍다 |
| 진행을 보며 판단·개입해야 하는 작업 | tmux | 화면과 스크롤백이 그대로 남는다 |
| 여러 창·페인을 동시에 봐야 하는 장애 대응 | tmux | 분할과 레이아웃이 자연스럽다 |
| tmux가 없는 오래된 서버·어플라이언스 | screen | 어디에나 있다. 그 외의 이유는 없다 |
| 재부팅 후에도 살아 있어야 하는 서비스 | systemd | 셋 다 답이 아니다 |
함께 보면 좋은 명령어
- nohup — 화면을 볼 필요가 없는 작업에는 tmux보다 가볍고 간단하다.
- screen — tmux가 설치돼 있지 않은 오래된 서버에서의 대안. 프리픽스가
Ctrl+a라는 점만 다르게 기억하면 된다. - watch — tmux 페인 하나를
watch -n1 'ss -s'로 채워 두면 상황판이 완성된다.