요즘 클로드 코드 등의 ai 도구를 다루게 되면서 tmux라는 걸 이용하면 터미널을 분할해서 작업할 수 있다~ 류의 이야기를 종종 듣게 된 것 같습니다. 그래서 tmux 사용법을 알아보던 중 세션, 윈도우같은 개념들이 나와 당황스럽기도 하고 tmux가 어떤 원리이길래 이런 게 가능한건지가 궁금해서 살펴봤었는데요. 찾아보니 tmux는 크게 두 가지를 해주는 도구였습니다.

 

 

  1. 터미널 에뮬레이터을 닫아도 그 안에서 돌던 작업이 죽지 않게 해줍니다. 노트북을 덮었다가 다시 열어도, SSH가 끊겼다가 다시 붙어도 작업을 그대로 이어서 할 수 있게 해줍니다.
  2. 하나의 터미널을 여러 영역으로 분할해서 여러 작업을 동시에 볼 수 있게 해줍니다. 한쪽에선 서버를 띄우고, 다른 쪽에선 로그를 보고, 또 다른 쪽에선 코드를 편집하는 식으로 활용할 수 있습니다.

 

 

이 두 가지가 어떻게 가능한지 살펴보던 과정에서 가장 중요했던 건 "터미널 에뮬레이터와 쉘 프로세스가 어떤 관계인가"였던 것 같습니다. 그래서 이 글에서는 그 관계부터 짚어보고, 그걸 tmux가 어떻게 바꿔놓는지, 그 위에서 패널, 윈도우, 세션이라는 단위들은 무엇을 의미하는지를 차례로 풀어보려고 합니다. 이 글을 통해 tmux가 어떤 원리의 도구인지, 그리고 왜 지금 다시 주목받고 있는지 이해할 수 있을 것으로 기대합니다.

 

※ tmux 사용법(단축키 등)은 이 글에서 다루지 않았습니다.

※ 이 글에서는 터미널 에뮬레이터로 Ghostty를 사용한 것을 기준으로 작성했습니다.

 

 

터미널 에뮬레이터


우선 터미널 에뮬레이터의 개념부터 알아야 합니다. Ghostty, iTerm2 같은 앱들을 터미널 에뮬레이터라고 부르는데요,. 이 앱들은 화면을 렌더링하는 롤, 구체적으론 키보드 입력을 받아 쉘 프로세스에 전달하고 쉘 프로세스의 출력을 화면에 표시하는 역할을 맡습니다.

 

실제로 ls, cd, cat 같은 명령어를 해석하고 OS에 전달하는 건 쉘 프로세스입니다(애당초 쉘 프로세스 자체가 명령어를 해석하는 프로세스입니다). Ghostty를 켜는 순간 내부적으로 시스템에 설정된 기본 쉘(제 맥북 기준으론 zsh)를 자식 프로세스로 생성하며, 구조로 보면 이렇습니다. 여담으로 운영체제 시간이었나? cat 등의 프로세스를 만들어보던 걸 실습해보던 기억이 났습니다

 

Ghostty (부모 프로세스)
  └── zsh (자식 프로세스)
        └── vim, python, ... (손자 프로세스)

 

 

저는 맥북에서 터미널 애뮬레이터로 Ghostty를 사용 중인데요, 실제로 pstree -p $$를 입력한 결과를 보면 다음처럼 Ghostty의 자식으로 zsh가 잡혀있는 것을 볼 수 있었습니다.

 

 

이를 통해 Ghostty를 끄게 되면 쉘 프로세스로 작업하던 내용들이 같이 종료되는 이유도 유추해볼 수 있습니다. 바로 SIGHUP(Signal Hang Up) 때문인데요, 부모 프로세스가 종료되면서 자식 프로세스들에게도 SIGHUP 신호가 전파되면서 함께 종료되는 것이 원인입니다.

 
Ghostty 종료
  ↓ SIGHUP 전송
zsh 종료
  ↓ SIGHUP 전송
vim, python, ... 종료
 
 

SSH로 원격 서버에 붙어 작업하다가 인터넷이 끊기면 작업이 날아가는 것도 같은 이유입니다. SSH 연결이 끊기는 순간 SIGHUP이 전파되어 실행 중이던 모든 프로세스가 종료됩니다.

 

 

 

tmux는


만약 쉘 프로세스가 Ghostty가 아닌 다른 독립적인 프로세스의 자식 프로세스라면 Ghostty를 꺼도 해당 쉘은 살아 있으니 쉘에 다시 붙을 수 있겠다는 아이디어를 얻을 수 있는데요, tmux가 바로 이 점을 활용하는 도구입니다. Ghostty가 아닌 tmux라는 독립적인 프로세스의 자식으로 쉘 프로세스들을 만들어두고, 이 쉘 프로세스들에 붙게 만들어주는 식으로 동작하게 되는 겁니다.

 

tmux를 실행하면 다음과 같은 일이 일어납니다.

 

1. tmux 서버 프로세스 생성

쉘에서 tmux 명령어 입력 시, tmux 서버 프로세스가 백그라운드에서 별도로 띄워집니다. (즉 쉘 프로세스의 자식으로 만들어지지 않습니다)

 

2. tmux 서버가 쉘 프로세스를 자식으로 생성

실제 작업이 이루어지는 쉘 프로세스는 tmux 서버의 자식 프로세스로 생성됩니다.

 

3. tmux 클라이언트가 tmux 서버에 연결

Ghostty 등의 터미널 애물레이터에서 보이는 것은 tmux 클라이언트로, tmux 서버와 소켓으로 연결되어 화면 출력만 주고받습니다.

 

구조를 정리하면 이렇습니다.

init (PID 1)
  └── tmux server          ← Ghostty와 무관한 독립 프로세스
        └── zsh            ← 실제 작업하는 쉘

Ghostty
  └── zsh
        └── tmux client    ← 서버에 연결만 하는 클라이언트
 
 
 

실제로 tmux를 통해 접속하게 된 쉘에서 pstree -p $$를 하게 되면, Ghostty에서 pstree -p $$를 했을 때와는 다르게 쉘 프로세스의 부모가 Ghostty가 아니라 tmux로 잡히는 것을 볼 수 있습니다.

 

 

 

정리하면, 결국 tmux는 터미널 애뮬레이터와 쉘 프로세스 사이에 독립적인 서버를 끼워 넣어서, 에뮬레이터가 꺼져도 쉘 프로세스는 살아있게 만드는 도구인 셈입니다. 그림으로 나타내면 다음과 같습니다.

 

 

이제 Ghostty를 닫으면 tmux 클라이언트는 죽지만 tmux 서버와 그 아래 zsh는 살아남아 있게 됩니다. Ghostty를 다시 열고 tmux attach를 입력하면 tmux 서버에 클라이언트가 다시 붙어 해당 쉘 프로세스에서 작업하던 것을 그대로 이어서 할 수 있게 됩니다.

 

 

 

패널, 윈도우, 세션


tmux에서는 패널, 윈도우, 세션이라는 개념을 사용합니다. 처음에는 세션 == 쉘 프로세스를 의미하는 것으로 오해하기 쉽지만 알고 보면 그렇지 않습니다. tmux 서버 아래로 여러 쉘 프로세스들이 만들어질 수 있는데, tmux가 이들을 논리적으로 묶어서 관리하는 단위가 바로 패널, 윈도우, 세션입니다.

 

구조는 세 계층으로 이루어져 있습니다.

 

패널(Pane)

가장 작은 단위를 말하며, 하나하나가 쉘 프로세스에 대응합니다. 

 

윈도우

패널들이 묶인 집단을 일컫는 단위입니다. 하나의 패널은 하나의 윈도우 안에 있고, 윈도우는 하나 이상의 패널로 구성되게 됩니다.

 

세션

윈도우들이 묶인 집단을 일컫는 단위입니다. 세션은 하나 이상의 클라이언트에 연결(attach)될 수 있고, 연결되면 클라이언트가 실행 중인 외부 터미널(ex: Ghostty)에도 표시됩니다.

 

 

패널 / 윈도우 / 세션의 관계를 도식화해보면 다음과 같습니다.

tmux server
  ├── 세션 A ("work")
  │     ├── 윈도우 1
  │     │     ├── 패널 1 (zsh)
  │     │     └── 패널 2 (zsh)
  │     └── 윈도우 2
  │           └── 패널 1 (zsh)
  └── 세션 B ("personal")
        └── 윈도우 1
              └── 패널 1 (zsh)
 
 
화면 기준으로 설명하면 다음과 같습니다. 파란색으로 표기한 영역이 패널, 빨간색으로 표기한 영역이 윈도우입니다.

 

 
 
 

그러면 왜 요즘 들어 tmux가 다시 주목을 받는가


최근 AI 에이전트들이 코딩을 해주는 워크플로가 보편화되면서, 그에 맞춰 tmux가 주목을 많이 받고 있는데요. 사실 tmux는 2000년대에 나온 도구로, 기술의 발전에 따라 최근에 나온 기술이 아닙니다. 이 도구가 다시 주목을 받는 이유는 다음처럼 정리해볼 수 있습니다.

 

  1. AI 에이전트는 오래 걸리는 작업을 백그라운드로 돌려둘 일이 많습니다. Claude Code 같은 도구에 개발이나 리팩토링, 또는 테스트 작성을 시켜두면 짧게는 몇 분, 길게는 수십 분이 걸립니다. 복잡한 작업을 시작했는데 회의 때문에 노트북을 닫아야 하는 상황 등이 생겨도 세션을 detach해두면 작업은 계속 돌릴 수 있습니다. 나중에 다시 attach하면 대화 기록과 실행 중이던 프로세스, 진행 중이던 빌드까지 그대로 이어서 할 수 있습니다.
  2. 멀티 에이전트 기반의 워크플로가 보편화되고 있습니다. 예전에 tmux 화면 분할의 사용 예시는 "코드를 편집하면서 서버 로그도 같이 보고 싶다" 정도로 추측해볼 수 있지만, 이제는 tmux 화면 분할을 통해 멀티 에이전트 기반으로 이뤄지는 작업을 봐야 하는 케이스들이 많습니다. 예를 들면 한 에이전트는 인증 모듈을 리팩토링하고, 다른 에이전트는 API 엔드포인트를 작성하고, 또 다른 에이전트는 테스트를 돌릴 때, 이 모든 걸 한 화면에서 보려면 결국 화면 분할이 필요합니다.

 

 

 

 

요즘은 클로드 코드 등이 알아서 tmux를 쓰기도 하기 때문에, 좋든 싫든 tmux를 몰라도 한 번쯤은 tmux를 마주하게 되는 것 같습니다. 이 글을 읽는 분들도 이 글을 통해 tmux의 기본 원리에 대해 이해할 수 있었으면 좋겠습니다

 

 

 

 

 

 

 

 

 

 

 

+ Recent posts