๐งท tmux ์ธ์ ๋ถํธ์คํธ๋ฉ โ ์ธ์ ๋งค๋์ ์ ๊ทธ ์์ด(์ ธ ์คํฌ๋ฆฝํธ)
๊ฐ์ ์ธ์ /์๋์ฐ/ํจ๋์ ๋งค๋ฒ ์์ผ๋ก ์ธํ ํ์ง ์์ผ๋ ค๋ฉด ์ธ์ ๋งค๋์ (tmuxpยทsmugยทtmuxinator)๊ฐ ์ ์. ๊ทธ ๋๊ตฌ๊ฐ ๋ด๋ถ์์ ๋ถ๋ฅด๋ tmux ๋ช ๋ น์ ์ ธ๋ก ํด๋ถํด ์๋ฆฌ๊น์ง ์ก๋๋ค.
๊ฐ์ ์์ ํ๊ฒฝ(์ธ์ ยท์๋์ฐยทํจ๋)์ ๋งค๋ฒ ์์ผ๋ก ์ธํ ํ์ง ์์ผ๋ ค๋ฉด ์ธ์ ๋ถํธ์คํธ๋ฉ์ด ๋ต์ด๋ค. ๊ทธ๋ฐ๋ฐ ์ด๊ฑด ์ด๋ฏธ ํด๊ฒฐ๋ ๋ฌธ์ ๋ค โ tmuxinator(2011~)ยทtmuxpยทsmug ๊ฐ์ ์ธ์ ๋งค๋์ ๊ฐ YAML ํ ์ฅ์ผ๋ก ๋ ์ด์์์ ์ ์ธํ๋ฉด ์์์ ๋์์ค๋ค. ๊ฒฐ๋ก ๋ถํฐ: ์ด๊ฑธ ์จ๋ผ. ๋งค๋ฒ ์ ธ๋ก ์ง์ ์ง๋ ๊ฑด ๋ฐํด ์ฌ๋ฐ๋ช ์ด๋ค.
๊ทธ๋ผ ์ด ๊ธ์ ์ ์
ธ ์คํฌ๋ฆฝํธ๊น์ง ๋ค๋ฃจ๋ โ ์ธ์
๋งค๋์ ๊ฐ ์์์ ํ๋ ์ผ์ด ์ ํํ ๊ทธ๊ฑฐ์ด๊ธฐ ๋๋ฌธ์ด๋ค. smug๋ tmuxinator๋ ๊ฒฐ๊ตญ tmux new-sessionยทsplit-window๋ฅผ ์์๋๋ก ๋ถ๋ฅด๋ ๋ํผ๋ค. ๊ทธ ์์ด์ ์
ธ๋ก ํ ๋ฒ ์ง๋ณด๋ฉด ๋๊ตฌ๊ฐ ๋ญ ๋์ ํด ์ฃผ๋์ง, ์ YAML ๋ช ์ค์ด ๊ทธ๋ ๊ฒ ๋์ํ๋์ง ์์ ์กํ๋ค. ๊ทธ๋์ ์ด ๊ธ์ (1) ์ ์์ธ ์ธ์
๋งค๋์ ๋ฅผ ๋จผ์ ์ธ์ฐ๊ณ โ (2) ๊ทธ ์๋ ๋ฉ์ปค๋์ฆ์ ์
ธ๋ก ํด๋ถํ๋ค. ์ฐ๋ผ๋ ๊ฑด ๋๊ตฌ๊ณ , ์
ธ์ ์๋ฆฌ๋ฅผ ๋ณด๊ธฐ ์ํ ํด๋ถ์ฉ์ด๋ค.
์ด ๊ธ์ tmux ๋ก๋๋งต์ 3๋จ๊ณ(์ธ์ ๋ถํธ์คํธ๋ฉ ์๋ํ) ๋ค. ์ ๋ฌธยท์ค์ ยทํ๋ฌ๊ทธ์ธ ๋จ๊ณ๋ ๋ก๋๋งต์์. ์ฌ๊ธฐ ๋์ค๋ ์ธ์ ๋งค๋์ ๋ 2๋จ๊ณ TPM ํ๋ฌ๊ทธ์ธ๊ณผ ๋ค๋ฅธ ์ถ โ tmux ์์์ ๋๋ ํ๋ฌ๊ทธ์ธ์ด ์๋๋ผ tmux ๋ฐ์ ์ธ๋ถ CLI๋ค.
1. ์ ์ โ ์ธ์ ๋งค๋์ ๋ก ์ ์ธํ๊ธฐ
๋ ์ด์์์ โ์ด๋ฐ ๋ชจ์โ์ด๋ผ๊ณ YAML๋ก ์ ์ผ๋ฉด ๋์ด๋ค. main ์ธ์
(์ข 1 + ์ฐ 2, 3-pane + secondary ์๋์ฐ)์ tmuxp๋ก ์ฎ๊ธฐ๋ฉด ์ด๋ ๊ฒ ๋๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
# ~/.config/tmuxp/main.yaml
session_name: main
start_directory: ~/ # ๋ชจ๋ pane ์์ ๋๋ ํ ๋ฆฌ โ ์
ธ์ `cd ~/`๊ฐ ํต์งธ๋ก ์ฌ๋ผ์ง๋ค
windows:
- window_name: main
layout: main-vertical # ์ข 1 + ์ฐ 2 ๋ถํ
panes: # ๋น pane 3๊ฐ ๋์ด = 3-pane
-
-
-
- window_name: secondary
panes:
-
tmuxp load main ํ ์ค์ด๋ฉด ์ด ์ธ์
์ด ๋ฌ๋ค(Python ํจํค์ง, pip install tmuxp). ์ธ ๋๊ตฌ ๋ค ์ด๋ฏธ ๋ ์์ผ๋ฉด ์๋ก ๋ง๋ค์ง ์๊ณ attachํ๋ค โ ์๋ ์
ธ ์คํฌ๋ฆฝํธ์ has-session ๋ถ๊ธฐ(ยง2)๊ฐ ๋๊ตฌ์์ ๊ธฐ๋ณธ ๋์์ผ๋ก ๋ค์ด ์๋ค.
smugยทtmuxinator๋ ๊ฑฐ์ ๊ฐ์ YAML์ด๋ค โ ํค ์ด๋ฆ๊ณผ ์ค์นยท๋ฐํ์๋ง ๋ค๋ฅด๋ค(์๋ ํ). smug๋ session:/root:์ brew install smug(Go ๋จ์ผ ๋ฐ์ด๋๋ฆฌ, ๋ฐํ์ 0), tmuxinator๋ name:์ gem install(Ruby)์ด๋ค.
์ด๋ ๊ฑธ ๊ณ ๋ฅด๋ โ ์กฐ๊ฑด๋ถ ์์
| ย | smug | tmuxp | tmuxinator |
|---|---|---|---|
| ๋ฐํ์ | Go ๋จ์ผ ๋ฐ์ด๋๋ฆฌ (๋ฌด์์กด) | Python | Ruby |
| ์ค์น | brew install smug | pip install tmuxp | gem install tmuxinator |
| ์คํ | smug start main | tmuxp load main | mux start main |
| ๊ฐ์ | ์ด์์ฑ โ ์๋ฒยท์ปจํ ์ด๋ ์ด๋์๋ | freeze๋ก ์ธ์
โconfig ์ญ์ถ์ถ | ์๋ฃยท์์ ์ต๋ค, ํด๋์ |
| ํ์ฑยท๋ชจ๋ฉํ | ๋์นยท์ ํ๋ (โ 0.9k, ~16์ปค๋ฐ/๋ ) | ์ต๋ค ํ๋์ด๋ ์ฌ์ค์ 1์ธ ๋ฉ์ธํ ์ด๋ โ ๏ธ (โ 4.5k, ~690์ปค๋ฐ/๋ ) | ์ฑ์ยท๊ธฐ๋๊ถ, ํ๋ ์ ์กฐํ๋ ์ปค๋ฎค๋ํฐ ๋์ (โ 13.7k, ~31์ปค๋ฐ/๋ ) |
์
๋ค ์ค์น ๋ช
๋ น์ด ์ ๊ฐ๊ฐ(brew/pip/gem)์ธ ๋ฐ์ ๋๋ฌ๋๋ฏ, TPM @plugin์ผ๋ก ๊น๋ ํ๋ฌ๊ทธ์ธ์ด ์๋๋ผ ๊ฐ์ ๋
๋ฆฝ ํ๋ก๊ทธ๋จ์ด๋ค. ์
ธ์์ ์ง์ ์คํํด tmux๋ฅผ ๋ฐ์์ ๋ถ๋ฆฐ๋ค.
- ๋ฌด๋ํ ๊ธฐ๋ณธ๊ฐ์ tmuxp โ ํ๋ ์ต๋ค์
freeze๋ก ์ง๊ธ ๋ ์๋ ์ธ์ ์ ๊ทธ๋๋ก config๋ก ์ญ์ถ์ถํ๋ค. Python๋ง ์์ผ๋ฉด(๋๋ถ๋ถ ์๋ค) ๊ฐ์ฅ ๋๊ฒ ๋ง๋๋ค. ๋จ ์ฌ์ค์ 1์ธ ๋ฉ์ธํ ์ด๋์ธ ๊ฑด ๊ฐ์. - ๋ฌด์์กดยท์ด์์ฑ์ด ์ต์ฐ์ (์๋ฒยท์ปจํ ์ด๋ ์ค๊ฐ)์ด๋ฉด smug โ ๋ฐํ์ 0, ๋จ์ผ ๋ฐ์ด๋๋ฆฌ. ํ๋์ ๋ฎ์ง๋ง ์ค์ ์ด ๋จ์ํด ๊นจ์ง ๊ฒ ๋ณ๋ก ์๋ค.
- ๋ ํผ๋ฐ์คยท์์ ๊ฐ ๋ง์์ผ ํ๋ฉด tmuxinator โ ์คํ 1์ยท์๋ฃ ์ต๋ค์ง๋ง Ruby ์์กด์ ์ ํ๋์ด๋ผ ์ง๊ธ ์๋ก ์์ํ ๊ฒฐ์ ์ ์ด์ ๋ ์ฝํ๋ค.
smug๋ฅผ ๊ณจ๋๋ค๋ฉด โ ์ค์ config์ ํ๋ฆฌ์ ์ ์๋ ์ปค์คํ ๋ ์ด์์ ์ก๋ ๋ฒ์ smug ์ฌํ ๊ธ์์ ์ด์ด์ง๋ค.
2. ์์ด โ ๋๊ตฌ๊ฐ ๋ถ๋ฅด๋ tmux ๋ช ๋ น
์ฌ๊ธฐ๋ถํฐ๋ โ์ฐ๋ ๋ฒโ์ด ์๋๋ผ โ์๋ฆฌโ๋ค. ์ YAML์ด ์คํ๋๋ฉด ์ธ์
๋งค๋์ ๊ฐ ๋ด๋ถ์์ ํ๋ ์ผ์ด ๊ฒฐ๊ตญ ์ด๊ฑฐ๋ค โ tmux ๋ช
๋ น์ ์์๋๋ก ๋ถ๋ฅด๋ ๊ฒ๋ฟ:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#!/usr/bin/env bash
set -euo pipefail
MAIN_SESSION="main"
SUB_SESSION="sub"
# ์ด๋ฏธ main ์ธ์
์ด ์์ผ๋ฉด ๋ฐ๋ก ๋ถ๊ธฐ (๋๊ตฌ์ "๋ ์์ผ๋ฉด attach"์ ํด๋น)
if tmux has-session -t "$MAIN_SESSION" 2>/dev/null; then
tmux attach -t "$MAIN_SESSION"
exit 0
fi
# 1) main ์ธ์
์์ฑ + ์ฒซ ์๋์ฐ
tmux new-session -d -s "$MAIN_SESSION" -n "main"
# 2) ์ฒซ ์๋์ฐ: ์ข/์ฐ ๋ถํ + ์ค๋ฅธ์ชฝ ์/ํ ๋ถํ (์ด 3 panes) โ ์ธ์
๋งค๋์ ์ layout: main-vertical
tmux split-window -h -t "$MAIN_SESSION":0
tmux split-window -v -t "$MAIN_SESSION":0.1
# ์์ ๋๋ ํ ๋ฆฌ ์ง์ โ tmuxp์ start_directory: ~/(smugยทtmuxinator์ root:) ํ ์ค์ด ๋์ ํ๋ ๋ถ๋ถ
tmux send-keys -t "$MAIN_SESSION":0.0 "cd ~/" C-m
tmux send-keys -t "$MAIN_SESSION":0.1 "cd ~/" C-m
tmux send-keys -t "$MAIN_SESSION":0.2 "cd ~/" C-m
# 3) main ๋ ๋ฒ์งธ ์๋์ฐ โ windows: ๋ชฉ๋ก์ secondary ํญ๋ชฉ
tmux new-window -t "$MAIN_SESSION" -n "secondary"
tmux send-keys -t "$MAIN_SESSION":1 "cd ~/" C-m
# 4) sub ์ธ์
์์ฑ โ ๋๊ตฌ์์ ๋ณดํต ํ์ผ ํ๋ = ์ธ์
ํ๋๋ผ, ๋ณ๋ config๊ฐ ๋๋ค
tmux new-session -d -s "$SUB_SESSION" -n "sub"
tmux send-keys -t "$SUB_SESSION":0 "cd ~/" C-m
# 5) main ์ฒซ ์๋์ฐ๋ก ์ด๋ ํ attach
tmux select-window -t "$MAIN_SESSION":0
tmux attach -t "$MAIN_SESSION"
ํ ์ค์ฉ ๋ณด๋ฉด ๋๊ตฌ์ ์ ์ฒด๊ฐ ๋๋ฌ๋๋ค โ new-session์ผ๋ก ์ธ์
์ ๋ง๋ค๊ณ , split-window๋ก ์ชผ๊ฐ๊ณ , send-keys๋ก ๋ช
๋ น์ ๋ฐ์ด๋ฃ๊ณ , attach๋ก ๋ถ๋๋ค. tmuxp์ layout: main-vertical์ ์ split-window ๋ ์ค์ด๊ณ , start_directory: ~/๋ ์ send-keys "cd ~/" ์ธ ์ค์ด๋ฉฐ, load ์ ์๋ attach๋ ๋ง์ง๋ง tmux attach๋ค. ๋งจ ์ has-session ๋ถ๊ธฐ๊ฐ โ์ด๋ฏธ ๋ ์์ผ๋ฉด attachโ์ ํด๋นํ๋ค. ๋๊ตฌ๋ ์ด ๋์ด์ YAML ๋ค์ ์จ๊ฒจ ์ค ๋ฟ, ํ๋ ์ผ์ ๋๊ฐ๋ค.
ํ ๊ฐ์ง ์ฐจ์ด โ ์ด ์คํฌ๋ฆฝํธ๋ mainยทsub ๋ ์ธ์
์ ํ ํ์ผ์ ๋ฃ์๋๋ฐ, ์ธ์
๋งค๋์ ๋ ๋ณดํต ํ์ผ ํ๋ = ์ธ์
ํ๋๋ค. ๋๊ตฌ๋ก ์ฎ๊ธฐ๋ฉด main.ymlยทsub.yml ๋๋ก ๊ฐ๋ผ์ง๋๋ฐ, ์ฉ๋๋ณ๋ก ๋ถ๋ฆฌ๋๋ ์คํ๋ ค ๊ด๋ฆฌ๊ฐ ๊น๋ํด์ง๋ค.
์คํ ๋ฐฉ๋ฒ (์ ธ ๋ฒ์ )
1
2
3
4
mkdir -p ~/bin
vi ~/bin/tmux-work.sh
chmod +x ~/bin/tmux-work.sh
~/bin/tmux-work.sh
3. ๋ง์ ธ๋ณด๋ tmux ํ๋ฆฌ๋ฏธํฐ๋ธ
๋๊ตฌ๊ฐ ๊ฐ์ธ๋ ๋ช ๋ น๋ค์ ์ง์ ๋ฐ๊ฟ ๋ณด๋ฉด ์๋ฆฌ๊ฐ ๋ ๋ถ๋๋ค.
โ ์๋์ฐ ์ด๋ฆ ๋ณ๊ฒฝ
1
2
3
tmux new-session -d -s "$MAIN_SESSION" -n "editor"
tmux new-window -t "$MAIN_SESSION" -n "api"
tmux new-window -t "$MAIN_SESSION" -n "ops"
โ ํจ๋ ์ด๋ฆ(ํ์ดํ) ์ง์
pane ์์ฒด์ โ์ด๋ฆโ์ ๋ถ์ด๋ ๊ฐ๋
์ ์๊ณ , ๋์ pane title์ ์ค์ ํด ํ์ํ๋ค. ํ์ ์์น๋ pane-border-format์ผ๋ก ์ ์ดํ๋ค.
1
2
3
4
5
6
7
8
# pane title ์ง์
tmux select-pane -t "$MAIN_SESSION":0.0 -T "editor"
tmux select-pane -t "$MAIN_SESSION":0.1 -T "logs"
tmux select-pane -t "$MAIN_SESSION":0.2 -T "shell"
# ํ์ดํ ํ์(ํ๋จ). ํ์ํ๋ฉด .tmux.conf์ ๋ฃ์ด๋ ๋จ
tmux set -g pane-border-status bottom
tmux set -g pane-border-format " #P: #T "
โ ํจ๋ ๋ ์ด์์ ๋ณ๊ฒฝ (์ข์ฐ 2๋ถํ )
1
tmux split-window -h -t "$MAIN_SESSION":0
โ ํน์ ํ๋ก์ ํธ ํด๋๋ก ์ด๋
1
2
tmux send-keys -t "$MAIN_SESSION":0.0 "cd ~/project" C-m
tmux send-keys -t "$MAIN_SESSION":1 "cd ~/project" C-m
4. ์ฐธ๊ณ
- ์ธ์
๋งค๋์ ๋ 2๋จ๊ณ TPM ํ๋ฌ๊ทธ์ธ๊ณผ ๋ค๋ฅธ ์ถ์ด๋ค. tmux ๋ฐ์ ์ธ๋ถ CLI์ด๊ณ ,
tmux-resurrect/continuum(๋ ์๋ ์ธ์ ์ ์ ์ฅโ๋ณต์)๊ณผ๋ ๋ชฉ์ ์ด ๋ค๋ฅด๋ค โ ์ธ์ ๋งค๋์ ๋ ๋ ์ด์์์ ์ฒ์๋ถํฐ ์ ์ธโ์์ฑํ๋ค. - ์ ์ธํ 3์ข ์ ๋ค ์ฑ์๊ธฐ โ ์์ฆ ๋ชจ๋ฉํ ์ ๋ค๋ฅธ ๋ฒ์ฃผ๋ค. sesh ๊ฐ์ ์จ๋๋งจ๋ ์ธ์ ์ค์์ฒ(fzfยทzoxide๋ก ๋๋ ํ ๋ฆฌ์์ ์ฆ์ ์ธ์ ์์ฑ)๋ก ์ค๋ ฅ์๋ค์ด ์ฎ๊ฒจ๊ฐ๋ ์ค์ด๋ค โ ์์ฑ 2.5๋ ์ โ 2.7k, ๋์ด ๋๋น ์ฑ์ฅ๋ฅ ์ด ์ด ์ ๋ณด๋ค ๋๋ค. ๊ณ ์ ๋ ์ด์์์ ์ ์ธํ๋ ์ด ๊ธ๊ณผ ๋ชฉ์ ์ด ๋ฌ๋ผ ์ค์ฝํ ๋ฐ์ด์ง๋ง, ๋ฐฉํฅ์ ์์๋ ๊ฒ. โ ์ด ํผ์ปค ๋ฒ์ฃผ์ ์ค์นยท๋ฐ์ธ๋ฉยท์ค์ ์ sesh โ ์ฆ์ tmux ์ธ์ ์ ํ์์ ์ด์ด์ง๋ค.
tmux has-session์ ์ธ์ ์กด์ฌ ์ฌ๋ถ๋ง ํ์ธํ๋ค. ๋๊ตฌ์ โ์ด๋ฏธ ์์ผ๋ฉด attachโ๊ฐ ์ด๊ฑธ ๋์ ํ๋ค.- ์ ธ๋ก ์ง์ ์ง๋ ๊ฒ ์ ์ผํด์ง๋ ๊ฑด ๋ฐ์ด๋๋ฆฌ ํ๋๋ ๋ชป ๊น๋ ๊ทนํ ํ๊ฒฝ(๋ฝ๋ค์ด๋ ์๋ฒ, ์์ ์ปจํ ์ด๋) ์ ๋๋ค. ๊ทธ ์ธ์ ์ธ์ ๋งค๋์ ๊ฐ ์์ํธํ์ด๋ค.