포슀트

πŸŒ€ tmux β€” 터미널 μ—΄ λ•Œλ§ˆλ‹€ μƒˆ μ„Έμ…˜μ΄ μƒκΈ°λŠ” 이유 (attach -t 함정)

μ…Έ μ‹œμž‘ μ‹œ tmux μžλ™ attach μŠ€λ‹ˆνŽ«μ΄ 맀번 빈 μ„Έμ…˜μ„ μƒˆλ‘œ λ§Œλ“œλŠ” 문제. `attach -t <이름>` ν•˜λ“œμ½”λ”©κ³Ό μ„Έμ…˜ 이름 λΆˆμΌμΉ˜κ°€ 원인이고, 타깃 μ—†λŠ” attach ν•œ μ€„λ‘œ ν•΄κ²°ν•œλ‹€. JetBrains IDE ν„°λ―Έλ„μ—μ„œ tmuxκ°€ μžλ™ μ‹€ν–‰λ˜λŠ” 것을 λ§‰λŠ” λ°©λ²•κΉŒμ§€.

πŸŒ€ tmux β€” 터미널 μ—΄ λ•Œλ§ˆλ‹€ μƒˆ μ„Έμ…˜μ΄ μƒκΈ°λŠ” 이유 (attach -t 함정)

이 글은 tmux λ‘œλ“œλ§΅μ˜ νŠΈλŸ¬λΈ”μŠˆνŒ… νŽΈμ΄λ‹€. μž…λ¬ΈΒ·μ„€μ •Β·ν”ŒλŸ¬κ·ΈμΈΒ·λΆ€νŠΈμŠ€νŠΈλž©κΉŒμ§€ 전체 κ²½λ‘œλŠ” λ‘œλ“œλ§΅μ—μ„œ.

증상

.zshrc(λ˜λŠ” .bashrc)에 β€œν„°λ―Έλ„μ„ μ—΄λ©΄ μžλ™μœΌλ‘œ tmux μ„Έμ…˜μ— λΆ™λŠ”β€ μŠ€λ‹ˆνŽ«μ„ λ„£μ–΄ 두고 μ“°λ‹€ 보면, μ–΄λŠ μˆœκ°„ 이런 μƒνƒœκ°€ λœλ‹€.

1
2
3
4
$ tmux ls
0-default:   2 windows (attached)
1-workspace: 2 windows
default:     1 windows        # ← 접속할 λ•Œλ§ˆλ‹€ ν•˜λ‚˜μ”© λŠ˜μ–΄λ‚˜λŠ” 빈 μ„Έμ…˜

μ •μž‘ μž‘μ—…ν•˜λ˜ μ„Έμ…˜(0-default)은 λ”°λ‘œ μžˆλŠ”λ°, μƒˆ 터미널을 μ—΄ λ•Œλ§ˆλ‹€ 아무것도 μ—†λŠ” default μ„Έμ…˜μ΄ 계속 μƒˆλ‘œ 생긴닀. λΆ™κΈ΄ λΆ™λŠ”λ° 맀번 빈 창에 λ–¨μ–΄μ§€λŠ” 것이닀.

문제의 μŠ€λ‹ˆνŽ«

μ…Έ μ‹œμž‘ μ‹œ μžλ™ attachλŠ” 보톡 이런 ν˜•νƒœλ‹€.

1
2
3
4
# tmux μžλ™ μ‹€ν–‰ (이미 tmux μ•ˆμ΄ 아닐 λ•Œλ§Œ, IDE λ‚΄μž₯ 터미널 μ œμ™Έ)
if command -v tmux &>/dev/null && [[ -z "$TMUX" ]] && [[ "$TERMINAL_EMULATOR" != "JetBrains-JediTerm" ]]; then
  tmux attach -t default || tmux new -s default
fi

각 쑰건의 μ˜λ―ΈλΆ€ν„° 짚으면:

  • command -v tmux β€” tmuxκ°€ μ„€μΉ˜λΌ μžˆμ„ λ•Œλ§Œ μ‹€ν–‰.
  • [[ -z "$TMUX" ]] β€” 이미 tmux μ„Έμ…˜ μ•ˆμ΄λ©΄ $TMUX에 μ†ŒμΌ“ κ²½λ‘œκ°€ λ“€μ–΄ μžˆλ‹€. μ•ˆμ—μ„œ 또 attachν•˜λ©΄ μ„Έμ…˜μ΄ μ€‘μ²©λ˜λ―€λ‘œ 밖에 μžˆμ„ λ•Œλ§Œ μ‹€ν–‰.
  • [[ "$TERMINAL_EMULATOR" != "JetBrains-JediTerm" ]] β€” JetBrains IDE λ‚΄μž₯ 터미널일 λ•ŒλŠ” tmux μžλ™ 싀행을 κ±΄λ„ˆλ›΄λ‹€. IntelliJΒ·PyCharm λ“± JetBrains IDEλŠ” λ‚΄μž₯ 터미널을 λ„μšΈ λ•Œ ν™˜κ²½λ³€μˆ˜ TERMINAL_EMULATOR=JetBrains-JediTerm을 λ„£μ–΄ μ€€λ‹€. 이 κ°’μœΌλ‘œ β€œμ§€κΈˆ IDE λ‚΄μž₯ 터미널인가”λ₯Ό νŒλ³„ν•œλ‹€.

IDE ν„°λ―Έλ„μ—μ„œ tmuxκ°€ μ œλ©‹λŒ€λ‘œ λœ¬λ‹€λ©΄ 이 쑰건이 λ°”λ‘œ κ·Έ 문제λ₯Ό λ§‰λŠ” μž₯μΉ˜λ‹€. .zshrc에 tmux μžλ™ 싀행을 λ„£μœΌλ©΄ JetBrains λ‚΄μž₯ 터미널을 μ—΄ λ•Œλ§ˆλ‹€ tmuxκ°€ μžλ™μœΌλ‘œ λ– μ„œ, IDEκ°€ κΈ°λŒ€ν•˜λŠ” 순수 μ…Έ λŒ€μ‹  tmux μ„Έμ…˜ μ•ˆμ— κ°‡νžŒλ‹€. IDE의 터미널 μ œμ–΄(μž‘μ—… 디렉토리 연동, 단좕킀 λ“±)와도 μΆ©λŒν•œλ‹€. $TERMINAL_EMULATOR둜 IDE 터미널을 감지해 κ·Έλ•Œλ§Œ μžλ™ 싀행을 λΉΌλ©΄ κΉ”λ”ν•˜κ²Œ ν•΄κ²°λœλ‹€.

μ—¬κΈ°κΉŒμ§€λŠ” 정상이닀. λ¬Έμ œλŠ” λ§ˆμ§€λ§‰ 쀄이닀.

1
tmux attach -t default || tmux new -s default

μ˜λ„λŠ” β€œdefault μ„Έμ…˜μ΄ 있으면 λΆ™κ³ , μ—†μœΌλ©΄ λ§Œλ“€μ–΄λΌβ€μ΄λ‹€. 그런데 μ‹€μ œ μ„Έμ…˜ 이름이 defaultκ°€ μ•„λ‹ˆλΌ 0-default라면?

원인 β€” attach -tλŠ” 이름을 (거의) μ •ν™•νžˆ λ§žμΆ°μ•Ό ν•œλ‹€

tmux attach -t defaultλŠ” defaultλΌλŠ” 타깃 μ„Έμ…˜μ„ μ°ΎλŠ”λ‹€. 그런데 μ‚΄μ•„μžˆλŠ” μ„Έμ…˜μ€ 0-defaultλ‹€. defaultλ‘œλŠ” 이 μ„Έμ…˜μ„ λͺ» μ°ΎλŠ”λ‹€.

-t의 λ§€μΉ­ κ·œμΉ™μ„ μ •ν™•νžˆ 보면 tmuxλŠ” 타깃 μ„Έμ…˜μ„ 접두어(prefix)둜 λ§€μΉ­ν•œλ‹€. 즉 tmux attach -t workλŠ” workspace μ„Έμ…˜μ— 뢙을 수 μžˆλ‹€. ν•˜μ§€λ§Œ 0-defaultλŠ” default둜 μ‹œμž‘ν•˜μ§€ μ•ŠμœΌλ―€λ‘œ -t defaultλ‘œλŠ” μ ˆλŒ€ λ§€μΉ­λ˜μ§€ μ•ŠλŠ”λ‹€. 접두어 맀칭은 μ•žμ—μ„œλΆ€ν„° λ§žμ•„μ•Ό ν•œλ‹€.

κ·Έλž˜μ„œ 흐름은 μ΄λ ‡κ²Œ λœλ‹€.

1
2
3
tmux attach -t default   # μ‹€νŒ¨ β€” 'default'λΌλŠ” μ΄λ¦„μ˜ μ„Έμ…˜μ΄ μ—†μŒ
||                       # κ·Έλž˜μ„œ λ’·λΆ€λΆ„μœΌλ‘œ λ„˜μ–΄κ°€κ³ 
tmux new -s default      # 맀번 μƒˆ 'default' μ„Έμ…˜μ„ 생성

접속할 λ•Œλ§ˆλ‹€ attachκ°€ ν—›λ‹€μ΄λΉ™ν•˜κ³  new둜 λΉ μ§€λŠ” 것. 이게 빈 μ„Έμ…˜μ΄ 계속 μŒ“μ΄λŠ” μ΄μœ λ‹€.

μ™œ μ„Έμ…˜ 이름에 0-, 1- 같은 접두어가 λΆ™λ‚˜

이 함정에 λΉ μ§€λŠ” μ „ν˜•μ μΈ κ²½μš°κ°€ μ„Έμ…˜ 정렬을 μœ„ν•΄ 이름에 숫자 접두어λ₯Ό λΆ™μ΄λŠ” μŠ΅κ΄€μ΄λ‹€.

tmux ls와 μ„Έμ…˜ 선택기(prefix + s)λŠ” μ„Έμ…˜μ„ 이름 μ•ŒνŒŒλ²³μˆœμœΌλ‘œ μ •λ ¬ν•œλ‹€. μ •λ ¬ μˆœμ„œλ₯Ό 직접 μ§€μ •ν•˜λŠ” μ˜΅μ…˜μ΄ μ—†κΈ° λ•Œλ¬Έμ—, μˆœμ„œλ₯Ό κ³ μ •ν•˜κ³  μ‹ΆμœΌλ©΄ 이름 μ•žμ— 번호λ₯Ό λΆ™μ΄λŠ” 게 ν”ν•œ 기법이닀.

1
2
3
0-default     # 항상 맨 μœ„
1-workspace   # κ·Έλ‹€μŒ
2-logs

μ •λ ¬μš©μœΌλ‘œλŠ” μ™„λ²½ν•˜κ²Œ λ™μž‘ν•œλ‹€. λ¬Έμ œλŠ” 이 접두어λ₯Ό μžλ™ attach μŠ€λ‹ˆνŽ«μ΄ λͺ¨λ₯Έλ‹€λŠ” 것뿐이닀. μŠ€λ‹ˆνŽ«μ€ μ—¬μ „νžˆ 접두어 μ—†λŠ” defaultλ₯Ό μ°Ύκ³  μžˆλ‹€.

ν•΄κ²° β€” 타깃을 μ•„μ˜ˆ λ–Όμ–΄λ‚Έλ‹€

핡심은 이름을 λ°”κΎΈλŠ” 게 μ•„λ‹ˆλΌ, attachν•  λ•Œ 이름을 ν•˜λ“œμ½”λ”©ν•˜μ§€ μ•ŠλŠ” 것이닀.

1
tmux attach || tmux new -s default

tmux attachλ₯Ό 타깃 없이 λΆ€λ₯΄λ©΄ tmuxλŠ” κ°€μž₯ μ΅œκ·Όμ— μ“°λ˜ μ„Έμ…˜μ— μžλ™μœΌλ‘œ λΆ™λŠ”λ‹€. 이름이 0-defaultλ“  1-workspaceλ“  상관없닀. tmux μ„œλ²„ μžμ²΄κ°€ 없을 λ•Œ(λΆ€νŒ… 직후 첫 μ‹€ν–‰ λ“±)만 attachκ°€ μ‹€νŒ¨ν•˜κ³ , κ·Έλ•Œ λΉ„λ‘œμ†Œ tmux new -s default둜 μƒˆ μ„Έμ…˜μ„ λ§Œλ“ λ‹€.

즉 두 κ°€μ§€κ°€ λ…λ¦½λœ κ΄€μ‹¬μ‚¬λ‘œ κΉ”λ”ν•˜κ²Œ λΆ„λ¦¬λœλ‹€.

관심사담당
μ„Έμ…˜ μ •λ ¬ μˆœμ„œμ„Έμ…˜ μ΄λ¦„μ˜ 숫자 접두어 (κ·ΈλŒ€λ‘œ μœ μ§€)
μ„Έμ…˜ 접속tmux attach (타깃 μ—†μŒ)

μ •λ ¬μš© μ ‘λ‘μ–΄λŠ” κ·ΈλŒ€λ‘œ 두고, β€œλ§€λ²ˆ μƒˆ μ„Έμ…˜ 생성” 문제만 사라진닀. 이름을 ν•˜λ“œμ½”λ”©ν•œ -t defaultκ°€ μœ μΌν•œ λ²„κ·Έμ˜€λ‹€.

νŠΉμ • μ„Έμ…˜μ— 항상 μ°©μ§€ν•˜κ³  μ‹Άλ‹€λ©΄

β€œμ΅œκ·Ό μ„Έμ…˜β€μ΄ μ•„λ‹ˆλΌ 항상 같은 μ„Έμ…˜μ— λ–¨μ–΄μ§€κ³  μ‹Άλ‹€λ©΄ 두 κ°€μ§€ 선택지가 μžˆλ‹€.

μ •ν™•ν•œ μ΄λ¦„μœΌλ‘œ 뢙이기 β€” 단, 접두어 λ²ˆν˜Έκ°€ λ°”λ€Œλ©΄ λ‹€μ‹œ κΉ¨μ§„λ‹€.

1
tmux attach -t 0-default

λ˜λŠ” new-session -A둜 β€œμžˆμœΌλ©΄ λΆ™κ³  μ—†μœΌλ©΄ λ§Œλ“€κΈ°β€λ₯Ό ν•œ μ€„λ‘œ ν•©μΉ˜κΈ°. -AλŠ” λŒ€μƒ μ„Έμ…˜μ΄ 이미 있으면 new λŒ€μ‹  attach처럼 λ™μž‘ν•œλ‹€.

1
tmux new-session -A -s default

이 방식은 항상 defaultλΌλŠ” κ³ μ • μ΄λ¦„μ˜ μ„Έμ…˜ ν•˜λ‚˜λ₯Ό μ˜€κ°„λ‹€. λ°˜λŒ€λ‘œ μ—¬λŸ¬ μ„Έμ…˜μ„ μœ λ™μ μœΌλ‘œ μ˜€κ°€λ©° β€œκ·Έλƒ₯ λ§ˆμ§€λ§‰μ— μ“°λ˜ κ³³β€μœΌλ‘œ λŒμ•„κ°€κ³  μ‹Άλ‹€λ©΄ 타깃 μ—†λŠ” tmux attachκ°€ λ§žλ‹€.

검증

λ°”κΎΌ λ’€μ—λŠ” μ‹€μ œλ‘œ 확인해 λ³Έλ‹€.

  1. μƒˆ 터미널 창을 μ—°λ‹€ β†’ κΈ°μ‘΄ μ„Έμ…˜(0-default λ“±)에 κ·ΈλŒ€λ‘œ λΆ™λŠ”κ°€?
  2. tmux ls둜 빈 μ„Έμ…˜μ΄ 더 이상 μŒ“μ΄μ§€ μ•ŠλŠ”μ§€ 확인.
  3. λͺ¨λ“  tmuxλ₯Ό 끄고(λ˜λŠ” μž¬λΆ€νŒ… ν›„) 처음 μ—΄μ—ˆμ„ λ•Œλ§Œ μƒˆ μ„Έμ…˜μ΄ λ§Œλ“€μ–΄μ§€λŠ”μ§€ 확인.

정리

  • μ…Έ μ‹œμž‘ μžλ™ attachμ—μ„œ attach -t <이름>을 ν•˜λ“œμ½”λ”©ν•˜λ©΄, μ‹€μ œ μ„Έμ…˜ 이름이 λ‹€λ₯Ό λ•Œ 맀번 μƒˆ μ„Έμ…˜μ΄ 생긴닀.
  • -tλŠ” 접두어 맀칭이라 0-defaultλŠ” default둜 λͺ» μ°ΎλŠ”λ‹€. μ •λ ¬μš© 숫자 접두어λ₯Ό μ“°λŠ” κ²½μš°κ°€ λŒ€ν‘œμ  함정.
  • tmux attach (타깃 μ—†μŒ) = κ°€μž₯ 졜근 μ„Έμ…˜μ— λΆ™κΈ°. μ„œλ²„κ°€ 없을 λ•Œλ§Œ μƒˆλ‘œ λ§Œλ“ λ‹€. μ •λ ¬ 접두어 μ›Œν¬ν”Œλ‘œμš°μ™€ μΆ©λŒν•˜μ§€ μ•ŠλŠ”λ‹€.
  • κ³ μ • μ„Έμ…˜ ν•˜λ‚˜λ§Œ μ›ν•˜λ©΄ tmux new-session -A -s <이름> ν•œ 쀄이 더 λͺ…ν™•ν•˜λ‹€.

κ΄€λ ¨ κΈ€

이 κΈ°μ‚¬λŠ” μ €μž‘κΆŒμžμ˜ CC BY 4.0 λΌμ΄μ„ΌμŠ€λ₯Ό λ”°λ¦…λ‹ˆλ‹€.