tmux는 터미널 세션을 서버에 붙여 두는 프로그램이다. SSH가 끊겨도 그 세션의 프로세스는 남고, 다시 붙으면 같은 화면이 나온다. 이 글의 키와 옵션은 tmux 3.2a의 기본값이다. `tmux -V`로 버전을 확인한다.

서버, 세션, 창, 칸

tmux는 네 겹이다.

- 서버는 백그라운드 프로세스 하나다. 첫 세션을 만들 때 같이 생기고, 세션이 하나도 없으면 같이 끝난다. - 세션은 그 서버 안의 작업 묶음이다. 이름을 붙이고, 붙었다 떨어졌다 한다. - 창은 세션 안의 화면 하나다. 번호가 있다. 기본 시작 번호는 0이다. - 칸은 창을 나눈 조각이다. 칸마다 프로세스가 하나 돈다. 기본 시작 번호도 0이다.

한 서버에 세션이 여러 개일 수 있고, 한 세션에 창이 여러 개, 한 창에 칸이 여러 개다.

설치와 첫 세션

Bash
sudo apt install tmux
tmux -V
tmux new-session -s work

`-s`는 세션 이름이다. 이름을 빼면 0, 1처럼 숫자가 붙는다. 이 명령은 만든 세션에 바로 붙는다.

지금 터미널은 그대로 두고 세션만 만들 때는 `-d`를 쓴다. `-c`는 그 세션이 시작할 디렉터리다.

Bash
tmux new-session -d -s app -c /srv/app

이미 같은 이름이 있을 때 새로 만들지 않고 붙고 싶으면 `-A`를 쓴다. 없으면 만들고, 있으면 `attach-session`처럼 동작한다.

Bash
tmux new-session -A -s work

목록, 붙기, 떨어지기

Bash
tmux list-sessions
tmux attach-session -t work

`list-sessions`는 `ls`로 줄여 쓴다. `attach-session`은 `attach` 또는 `a`다.

붙어 있는 상태에서 떨어지려면 접두키 다음 `d`다. 기본 접두키는 Ctrl-b다. Ctrl-b를 누르고 손을 뗀 뒤 `d`를 누른다. 세션은 서버에 남고 지금 터미널만 빠져나온다.

SSH 창을 그냥 닫아도 세션은 남는다. 끊기는 것은 tmux에 붙어 있던 클라이언트다. 칸 안의 프로세스는 서버 쪽에 있다.

같은 세션에 클라이언트를 둘 이상 붙일 수 있다. 붙인 쪽은 같은 화면을 본다. 한쪽에서 칸을 바꾸면 다른 쪽도 따라간다.

밖에 있는 터미널에서 붙어 있는 클라이언트만 떨어뜨릴 수도 있다.

Bash
tmux detach-client -s work

세션이 있는지는 종료 상태로 본다. 있으면 0, 없으면 0이 아니다.

Bash
tmux has-session -t app

접두키

세션 안의 단축키는 거의 모두 접두키 뒤에 온다. 기본은 Ctrl-b다. 키 목록은 Ctrl-b 다음 `?`다. 목록에서 나오려면 `q`다.

명령 줄은 Ctrl-b 다음 `:`다. 여기에 `split-window -h` 같은 tmux 명령을 직접 넣는다.

접두키 자체를 칸 안의 프로그램에 보내려면 Ctrl-b를 한 번 더 누른다. 기본 바인딩이 `send-prefix`다.

창

Ctrl-b 다음 키다. 접두키를 누른 채 같이 누르는 것이 아니다.

- `c`는 새 창이다. - `n`은 다음 창, `p`는 이전 창, `l`은 직전 창이다. - `0`부터 `9`는 그 번호의 창이다. - `,`는 창 이름을 묻는다. - `w`는 창 목록이다. - `&`는 창을 끝낼지 묻는다.

밖에서 창을 만드는 명령이다. `-n`은 창 이름, `-c`는 그 창의 시작 디렉터리다.

Bash
tmux new-window -t work -n logs -c /var/log

칸

Ctrl-b 다음 `%`는 지금 칸의 오른쪽에 새 칸을 만든다. 매뉴얼의 `split-window -h`다. 가로로 나뉘고, 크기 단위는 열이다.

Ctrl-b 다음 `"`는 지금 칸의 아래에 새 칸을 만든다. 매뉴얼의 `split-window -v`이고, 이쪽이 기본이다. 세로로 나뉘고, 크기 단위는 줄이다.

칸 이동도 접두키를 떼고 누른다.

- 화살표는 그 방향의 칸으로 간다. 한 번 접두키를 누른 뒤 화살표를 이어서 누를 수 있다. - `o`는 다음 칸이다. - `q`는 칸 번호를 잠깐 보여 준다. 번호가 보이는 동안 그 숫자를 누르면 그 칸으로 간다. - `z`는 지금 칸을 창 전체에 펼쳤다 되돌린다. - `x`는 칸을 끝낼지 묻는다. - `{`와 `}`는 칸의 자리를 바꾼다.

칸 크기는 Ctrl-b 다음 Ctrl-화살표다. 한 번에 한 줄 또는 한 열이다. Alt-화살표는 한 번에 다섯이다.

Bash
tmux split-window -h -t work:0 -c /var/log

`-t work:0`은 work 세션의 0번 창이다. 칸까지 지정하려면 `work:0.0`처럼 창 번호 뒤에 칸 번호를 붙인다.

스크롤과 복사

화면 위로 올라간 출력은 스크롤백에 쌓인다. `history-limit` 기본값은 2000줄이다.

과거 줄을 보려면 Ctrl-b 다음 `[`로 복사 모드에 들어간다. 화살표와 Page Up, Page Down으로 움직인다. `q` 또는 Escape로 나온다.

기본 키 모드는 emacs다. 이 모드에서 선택은 Ctrl-Space로 시작하고, Ctrl-w로 버퍼에 넣은 뒤 복사 모드에서 나온다. Space는 선택이 아니라 한 페이지 아래로 이동이다.

`mode-keys`를 vi로 바꾸면 선택이 Space, 복사가 Enter가 된다. 설정 파일에 넣는 줄은 아래 설정 절에 있다.

복사한 내용은 Ctrl-b 다음 `]`로 지금 칸에 붙여 넣는다.

`mouse` 기본값은 off다. 꺼져 있으면 휠은 바깥 터미널의 스크롤이고, tmux 스크롤백이 아니다. 마우스로 스크롤백을 움직이려면 `mouse`를 켠다.

세션이 끝나는 때

`remain-on-exit` 기본값은 off다. 칸 안의 프로그램이 끝나면 그 칸은 사라진다. 창의 마지막 칸이면 창도 사라지고, 세션의 마지막 창이면 세션도 사라진다.

세션을 만들 때 명령을 인자로 주면, 그 명령이 칸의 프로세스다. 셸이 아니다.

Bash
tmux new-session -d -s app -c /srv/app './server'

이 칸에 Ctrl-C를 보내면 `./server`가 끝나고, 칸이 닫히며 세션까지 사라진다.

Bash
tmux send-keys -t app C-c

명령을 셸 안에서 돌리면 다르다. 세션을 셸로 만든 뒤 `send-keys`로 명령을 실행하면, 부모는 셸이다. Ctrl-C는 그 명령만 끝내고 셸은 남으므로 세션도 남는다.

Bash
tmux new-session -d -s app -c /srv/app
tmux send-keys -t app './server' Enter

`Enter`는 글자를 넣은 뒤 실행한다. 빼면 입력만 되고 실행되지 않는다.

프로그램이 끝나도 칸을 남기려면 창 옵션 `remain-on-exit`를 켠다. on이면 종료와 상관없이 칸이 남고, failed면 종료 상태가 0이 아닐 때만 남는다. 남은 칸은 `respawn-pane`으로 다시 띄운다.

Bash
tmux set-option -t app remain-on-exit on

이 옵션은 창 옵션이다. 세션 이름만 주면 그 세션의 현재 창에 적용된다.

이름과 종료

Bash
tmux rename-session -t work desk
tmux kill-session -t app
tmux kill-server

`kill-session`은 그 세션의 칸을 모두 끝낸다. `kill-server`는 이 서버에 있는 세션을 모두 끝낸다.

떨어지기와 죽이는 일은 다르다. `detach`와 SSH 종료는 프로세스를 남긴다. `kill-session`과 칸의 Ctrl-C는 그 프로세스를 끝낸다.

세션 안에서 이름을 바꿀 때는 Ctrl-b 다음 `$`가 세션 이름, `,`가 창 이름이다.

설정 파일

`~/.tmux.conf`는 서버가 처음 뜰 때 읽는다. 이미 서버가 떠 있으면 다시 읽혀야 한다.

Bash
set -g mouse on
set -g history-limit 10000
set -g base-index 1
setw -g pane-base-index 1
set -g renumber-windows on
setw -g mode-keys vi

`base-index`와 `pane-base-index`는 창과 칸 번호를 1부터 시작한다. `renumber-windows`는 가운데 창을 닫아도 번호를 비워 두지 않고 다시 매긴다. `mode-keys vi`는 복사 모드의 키만 바꾼다. 접두키 뒤의 창 단축키는 그대로다.

`history-limit`을 줄이면 이미 쌓인 줄도 그 길이로 잘린다.

접두키를 Ctrl-a로 바꾸는 예다. 안의 프로그램에도 Ctrl-a가 필요하면, 바꾼 접두키를 한 번 더 눌러 `send-prefix`로 보낸다.

Bash
unbind C-b
set -g prefix C-a
bind C-a send-prefix

떠 있는 서버에 파일을 다시 읽힌다.

Bash
tmux source-file ~/.tmux.conf

`mouse`와 `history-limit`은 읽은 뒤의 동작에 바로 먹는다. 번호 시작값을 바꿔도, 이미 만들어 둔 창의 번호가 즉시 1로 다시 매겨지는 것은 아니다. 그 뒤에는 새 창에 적용된다.

긴 프로세스를 두는 순서

디렉터리를 정하고, 이름을 붙이고, 떨어져 있는 세션에서 명령을 실행한다. 나중에 붙어서 출력을 보고, Ctrl-b 다음 `d`로 나온다.

Bash
tmux new-session -d -s app -c /srv/app './server'
tmux attach-session -t app

명령을 세션의 프로세스로 둔 구성이다. 이 프로세스가 끝나면 세션도 끝난다. 셸을 남긴 채 명령을 다시 넣고 싶으면, 앞의 `send-keys` 구성을 쓴다.