미래의 터미널
(jyn.dev)- 기존 터미널 구조의 복잡성과 한계를 지적하며, 입력·출력·프로세스 제어를 새롭게 통합한 차세대 터미널 개념 제시
- Jupyter Notebook을 모델로 삼아, 이미지 렌더링·명령 재실행·편집 가능한 출력·내장 편집기 등 상호작용형 인터페이스 구현 가능성 탐색
- Warp와 iTerm2의 사례를 통해 쉘과 터미널 간 심층 통합(shell integration) , 장기 실행 프로세스 관리, 세션 분리·복구 기능을 구체적으로 설명
- 데이터플로 추적(dataflow tracking) 과 영속성(persistence) 을 기반으로, 명령의 undo/redo, 자동 재실행, 협업형 터미널 등 확장 기능 구상
- 단계별 접근을 통해 트랜잭션형 CLI → 지속 세션 → 구조화된 RPC → Jupyter형 프런트엔드로 발전시키는 점진적 구축 전략 제시
터미널의 기본 구조
- 터미널은 네 가지 구성요소로 이루어짐: 터미널 에뮬레이터, 가상 터미널(PTY) , 쉘, 프로세스 그룹
- 터미널 에뮬레이터는 화면에 그리드 구조를 렌더링하는 프로그램
- PTY는 커널 내부 상태로, 입력을 프로세스 그룹에 전달하고 신호(signal) 변환을 담당
- 쉘은 입력을 읽고 파싱하며 프로세스를 생성하는 이벤트 루프 역할
- 프로세스들은 입력·출력을 통해 위 구성요소들과 상호작용
- 입력은 단순한 텍스트가 아니라 신호(signal) 를 포함하며, 출력은 ANSI 이스케이프 시퀀스로 구성되어 포맷팅을 표현
더 나은 터미널의 구상
- 기존 터미널은 기능적 제약이 많아 확장성과 상호작용성이 부족함
-
Jupyter Notebook은 전통적인 VT100 에뮬레이터에서 불가능한 기능 제공
- 고해상도 이미지 렌더링
- 과거 출력을 추가하지 않고 교체하는 "처음부터 재실행" 버튼
- 소스 코드와 출력을 제자리에서 다시 작성 가능한 "뷰" (예: 마크다운을 소스 또는 렌더링된 HTML로 표시)
- 구문 강조, 탭, 패널, 마우스 지원 등이 있는 내장 편집기
- 하지만 셸을 커널로 사용하는 Jupyter 노트북 개념은 여러 문제 직면
- 셸이 명령을 한 번에 받아 탭 완성, 구문 강조, 자동 제안이 작동하지 않음
- 장시간 실행 프로세스 처리 문제: Jupyter는 기본적으로 셀이 완료될 때까지 실행하며, 취소는 가능하지만 일시 중지, 재개, 상호작용, 실행 중 프로세스 보기 불가능
- "셀 재실행" 버튼이 컴퓨터 상태에 문제 초래 (특히
rm -rf같은 명령 포함 시) - 실행 취소/재실행이 작동하지 않음
이게 어떻게 동작할까?
-
쉘 통합 (Shell Integration)
- Warp 터미널은 터미널과 셸 간 네이티브 통합 구축
- 각 명령의 시작과 끝, 출력, 사용자 입력을 터미널이 이해
- 표준 기능(사용자 정의 DCS)을 사용하여 구현
- iTerm2도 유사한 방식으로 OSC 133 이스케이프 코드 사용 가능
- 단일 단축키로 명령 간 탐색
- 명령 완료 시 알림
- 출력이 화면 밖으로 나가면 현재 명령을 "오버레이"로 표시
- Warp 터미널은 터미널과 셸 간 네이티브 통합 구축
-
장기 실행 프로세스 관리
-
상호작용(interacting) :
- 장시간 실행 프로세스와 상호작용하려면 양방향 통신 필요
- TUI 예시:
top,gdb,vim - Jupyter는 변경 및 업데이트 가능한 인터랙티브 출력 설계에 강점
- TUI 예시:
- 예상되는 터미널 기능: 항상 "자유 입력 셀" 제공
- 인터랙티브 프로세스가 창 상단에서 실행되고 하단에 입력 셀 제공
- 장시간 실행 프로세스와 상호작용하려면 양방향 통신 필요
-
일시중단(suspending) :
- 프로세스 "일시 중지"는 "작업 제어(job control)"로 불림
- 현대 터미널은 일시 중지 및 백그라운드 프로세스를 지속적인 시각적 표시로 보여줄 것으로 예상
- IntelliJ가 하단 작업 표시줄에 "인덱싱 중..."을 표시하는 방식과 유사
-
연결해제(disconnecting) : 세션 분리·복구를 위해 세 가지 접근 존재
- Tmux / Zellij / Screen: 터미널 에뮬레이터와 프로그램 사이에 추가 터미널 에뮬레이터 주입. 서버가 PTY를 소유하고 출력을 렌더링하며, 클라이언트가 실제 터미널 에뮬레이터에 출력 표시. 클라이언트 분리, 재연결, 다중 클라이언트 동시 연결 가능. iTerm은 tmux 클라이언트를 우회하고 서버와 직접 통신하는 자체 클라이언트로 작동
- Mosh: SSH 대체. 네트워크 중단 후 터미널 세션에 재연결 지원. 서버에서 상태 머신을 실행하고 뷰포트의 증분 차이를 클라이언트에 재생. 멀티플렉싱 및 스크롤백은 터미널 에뮬레이터가 처리할 것으로 예상. 클라이언트가 네트워크 측에서 실제로 실행되므로 로컬 라인 편집이 즉각적
- alden/shpool/dtach/abduco/diss: 클라이언트/서버로 세션 분리/재개만 처리하며, 네트워킹이나 스크롤백은 포함하지 않고 자체 터미널 에뮬레이터도 포함하지 않음. tmux 및 mosh에 비해 높은 분리 수준
-
상호작용(interacting) :
-
재실행과 되돌리기
- 해결책은 데이터 플로우 추적
-
pluto.jl이 Julia 컴파일러에 연결하여 오늘날 구현
- 이전 셀에 의존하는 셀을 실시간으로 업데이트
- 종속성이 변경되지 않은 경우 셀을 업데이트하지 않음
- 스프레드시트와 유사한 Jupyter로, 필요할 때만 코드 재실행
-
직교 지속성(orthogonal persistence) 을 통한 일반화
- 프로세스를 샌드박스화하고 모든 I/O를 추적하며, 샌드박스 내 다른 프로세스와 통신하지 않는 한 "너무 이상한" 것들 방지
- 프로세스를 입력의 순수 함수로 취급 가능, 입력은 "전체 파일 시스템, 모든 환경 변수, 모든 프로세스 속성"
파생 기능
-
Jupyter 프런트엔드 필요:
- Runbooks (실제로는 Jupyter와 PTY 프리미티브만으로 구축 가능)
- 이상한 사용자 정의 언어나 ANSI 색상 코드 없이 일반 CSS를 사용하는 터미널 커스터마이징
- 출력/타임스탬프로 명령 검색: 현재 세션의 출력 전체에서 검색하거나 모든 명령 입력 기록에서 검색할 수 있지만, 스마트 필터가 없고 출력이 세션 간 지속되지 않음
-
쉘 통합 필요:
- 각 명령의 타임스탬프 및 실행 시간
- 네트워크 경계를 넘어서도 로컬 라인 편집
- 탭을 누르지 않고도 셸 명령에 대한 IntelliSense, 터미널에 통합된 렌더링
-
샌드박스 추적 필요:
- 샌드박스 추적의 모든 기능: 협업 터미널, 명령으로 수정된 파일 쿼리, 런타임에 편집 가능한 asciinema, 빌드 시스템 추적
- 명령 실행 시점의 디스크 상태로도 검색하도록 스마트 검색 확장
- 실행 취소/재실행을 git과 유사한 분기 모델로 확장 (emacs undo-tree가 이미 지원), 프로세스 트리의 여러 "뷰" 제공
- undo-tree 모델과 샌드박싱을 통해 LLM에게 프로젝트 액세스 권한을 부여하고 여러 개를 동시에 병렬로 실행 가능, 서로의 상태를 덮어쓰지 않으며 작업 내용 확인, 편집, 나중에 사용할 runbook으로 저장 가능
- 프로덕션 환경에서 머신 상태에 영향을 주지 않고 기존 상태만 검사하는 터미널
단계별 구축 전략
-
1단계: 트랜잭션 시맨틱 (transactional semantics)
- 터미널 재설계 시 터미널 에뮬레이터부터 시작하는 것이 잘못된 접근
- 사용자가 에뮬레이터에 애착을 가지며 구성, 외관, 키 바인딩 설정
- 에뮬레이터 전환 비용이 높음
- CLI 레이어에서 시작하는 것이 올바른 방법
- CLI 프로그램은 설치 및 실행이 쉽고 전환 비용이 매우 낮음
- 전체 워크플로를 변경하지 않고 일회성으로 사용 가능
-
터미널용 트랜잭션 의미론을 구현하는 CLI 작성
-
transaction [start|rollback|commit]같은 인터페이스 -
start후 실행된 모든 것을 실행 취소 가능 - 이것만으로도 전체 비즈니스 구축 가능
-
- 터미널 재설계 시 터미널 에뮬레이터부터 시작하는 것이 잘못된 접근
-
2단계: 지속 세션 (Persistent Sessions)
- 트랜잭션 시맨틱 확보 후 tmux 및 mosh에서 지속성 분리
- PTY 지속성을 얻으려면 클라이언트/서버 모델 도입 필요
- 커널이 PTY 양쪽이 항상 연결되어 있을 것으로 예상
- alden 같은 명령이나 유사 라이브러리 사용으로 터미널 에뮬레이터나 PTY 세션 내부에서 실행 중인 프로그램에 영향을 주지 않고 단순하게 구현
- 스크롤백 확보를 위해 서버가 입출력을 무기한 저장하고 클라이언트 재연결 시 재생
- 터미널 에뮬레이터가 다른 출력처럼 처리하는 네이티브 스크롤백 제공
- 임의의 시작점에서 재생 및 재개 가능
- ANSI 이스케이프 코드 파싱 필요하지만 충분한 작업으로 가능
- mosh와 같은 네트워크 재개를 위해 Eternal TCP 사용 (QUIC 위에 구축하여 효율성 향상 가능)
- PTY 지속성과 네트워크 연결 지속성 분리
- Eternal TCP는 순수한 최적화:
ssh host eternal-pty attach를 루프로 실행하는 bash 스크립트 위에 구축 가능
- 이 시점에서 tmux처럼 단일 터미널 세션에 여러 클라이언트 연결 가능, 창 관리는 여전히 터미널 에뮬레이터가 처리
- 통합 창 관리를 원하면 터미널 에뮬레이터가 iTerm처럼 tmux -CC 프로토콜 사용 가능
- 이 단계의 모든 부분은 트랜잭션 의미론과 독립적으로 병렬로 수행 가능하지만, 비즈니스 구축에는 충분하지 않음
-
3단계: 구조화된 RPC
- 클라이언트/서버 모델에 의존
- 터미널 에뮬레이터와 클라이언트 사이에 서버가 개입하면 메타데이터로 I/O 태깅 같은 기능 구현 가능
- 모든 데이터에 타임스탬프 추가 가능
- 입력과 출력 구별 가능
- xterm.js가 이와 유사하게 작동
- 셸 통합과 결합하면 데이터 레이어에서 셸 프롬프트와 프로그램 출력 구별 가능
-
터미널 세션의 구조화된 로그 확보
- asciinema처럼 로그를 녹화로 재생
- 모든 명령을 재실행하지 않고 셸 프롬프트 변환
- Jupyter Notebook 또는 Atuin Desktop으로 가져오기
- 명령을 저장하고 나중에 스크립트로 재실행
- 터미널이 데이터가 됨
-
4단계: Jupyter 유사 프론트엔드
-
터미널 에뮬레이터를 처음으로 건드리는 단계이며 의도적으로 마지막 단계
- 전환 비용이 가장 높기 때문
- 구축된 모든 기능을 활용하여 좋은 UI 제공
-
transactionCLI는 중첩 트랜잭션을 원하지 않는 한 더 이상 필요하지 않음- 전체 터미널 세션이 기본적으로 트랜잭션으로 시작
- 모든 조각을 결합했기 때문에 위에서 언급한 모든 파생 기능 제공
-
터미널 에뮬레이터를 처음으로 건드리는 단계이며 의도적으로 마지막 단계
결론
- 이 구조는 대담하고 야심 차며 전체 구축에 약 10년까지 소요될 것으로 예상
- 인내심을 가지고 단계별로 진행할 것
- 이 글이 누군가에게 영감을 주어 직접 구축을 시작하기를 희망
Hacker News 의견
-
글 전체를 읽어보니, 처음엔 단순히 NIH식 바람 목록처럼 보였음
이미 터미널을 대체할 수 있는 여러 대안이 있음에도 글에서는 언급이 없었음
예를 들어 Emacs는 Lisp 기반의 VM으로, 함수 재정의가 쉽고 명령은 주석이 달린 함수임. 출력은 버퍼로 관리되고, 여러 창과 프레임을 타일 형태로 배치할 수 있음. CLI를 그대로 사용할 수도 있고(vterm, eat 등), REPL 흐름으로 전환할 수도 있음(shell-mode, eshell 등). 그래픽도 지원하지만 완전한 2D 컨텍스트는 아님
또 다른 예로 Acme는 Emacs와 비슷하지만, 모든 텍스트가 명령이 될 수 있는 인터랙티브 텍스트 환경임. Smalltalk도 비슷한 철학을 가졌지만 IDE에 더 가까움- Emacs에는 Org-mode와 org-babel이 있어서 Jupyter notebook처럼 작동할 수 있음. 심지어 Jupyter 커널과도 통신 가능함
나는 Emacs에서 GPTel을 활용해 오래된 라틴어 교재 PDF를 자동으로 잘라내고, OCR을 통해 org-mode 형식으로 변환함. 그 결과, 단어를 선택하면 즉시 사전 검색이 가능하고, 문장을 선택하면 LLM이 문법 분석을 해줌. 1970년대 텍스트 에디터가 미래형 학습 플랫폼이 된 셈임 - Acme에 대해 더 알고 싶음. 검색하기 어렵더라.
Emacs, Jupyter, VSCode 같은 플랫폼은 강력하지만 완성된 애플리케이션이라기보단 커스터마이징 기반의 플랫폼임.
진짜 혁신이라면, 복잡한 설정 대신 도커 컨테이너나 실행 파일 형태로 쉽게 재현 가능한 형태로 배포해야 함 - 글의 핵심은 터미널의 데이터 모델을 개방하는 것이라 생각함. 그 위에서 다양한 기능을 구현할 수 있다는 점이 중요함
- Emacs의 독특한 점은 UI 독립성임. Elisp로 작성된 앱은 터미널과 GUI 모두에서 동일하게 작동함. 20년 전에도 터미널에서 Elisp를 작성했는데, GUI 사용자들은 그 차이를 전혀 느끼지 못했음. 이런 플랫폼은 다른 곳엔 없음
- Emacs에는 Org-mode와 org-babel이 있어서 Jupyter notebook처럼 작동할 수 있음. 심지어 Jupyter 커널과도 통신 가능함
-
터미널의 후속 개념이 꼭 텍스트 기반일 필요가 있는지 의문임
미래의 터미널은 API 형태일 수도 있고, OAuth 인증을 통해 원격 호출이 가능할 수도 있음. 입력과 출력이 더 이상 CLI 텍스트가 아닐 수도 있음.
대신 객체 기반 입력/출력으로 전환해, 명령어와 데이터 구조를 API로 탐색 가능하게 만들 수 있음.
터미널은 70년대의 유산이며, 오늘날엔 더 나은 대안이 충분히 가능함- 터미널은 사실 텍스트 중심이 아니라 양방향 토큰 스트림 기반임. 이 단순함 덕분에 Unix식 조합이 가능함.
JSON 출력을 추가하면jq같은 도구로 파이프라인을 구성할 수 있음.
단순함이 장점인 “worse is better” 철학 덕분에 수십 년간 진화해왔음 - 나도 CLI의 표준 입출력 한계에 공감함. 데이터와 표현이 동일하다는 점이 조합성을 제한함.
PowerShell처럼 자기 기술적 객체를 주고받으면 훨씬 강력한 조합이 가능함
관련 예시는 내 블로그 글에 정리했음 - PowerShell은 흥미롭지만, 점점 프로그래밍 언어에 가까워지는 단점이 있음.
명령어 기반의 직관적 흐름이 사라지고, API 구조를 외워야 함.
AI 기반 자동완성과 객체 구조 탐색 기능이 있다면 이 약점을 보완할 수 있을 것임 - 나도 Nushell을 즐겨 씀. PowerShell보다 깔끔하고, Microsoft 의존성이 없음
https://www.nushell.sh/ - 이미 비텍스트 기반 터미널 대안은 존재함.
하지만 텍스트 기반의 진화형 터미널은 여전히 상상 가능한 구체적 제안이 있어야 흥미로움
- 터미널은 사실 텍스트 중심이 아니라 양방향 토큰 스트림 기반임. 이 단순함 덕분에 Unix식 조합이 가능함.
-
터미널이 지금까지 살아남은 이유는 호환성과 자동화 가능성 때문임
GUI보다 스크립트화가 쉽고, 모든 것이 재현 가능하며 검색 가능함
예전엔 Neovim의 alt-screen 전환이 불편했지만, 이런 세세한 UX도 중요함
나는 컴퓨터를 처음 접했을 때, 그리고 터미널을 배웠을 때 두 번 사랑에 빠졌음 -
관련 프로젝트로는
-
18개월 전 Windows Terminal에서 비슷한 실험을 해봤음
GitHub 코멘트에 기록되어 있음
하지만 Polyglot Notebooks를 써본 후, 그쪽이 훨씬 자연스러워서 전환함
명령형 백엔드를 Jupyter 커널로 바꿔서, 노트북 스타일의 인터랙티브 문서로 사용하는 게 훨씬 효율적임- 나도 이런 시스템을 찾고 있었음. LLM이나 개인 작업 환경에 더 적합할 듯함
- Windows Terminal에 노트북 개념을 넣는 건 정말 멋진 아이디어임. 이런 시도가 더 많아지길 바람
-
예전에 TopShell이라는 프로젝트로 함수형 프로그래밍 기반의 셸+터미널을 만들었음
https://github.com/topshell-language/topshell#readme
가능성은 있지만 완전한 대안이 되려면 아직 많은 작업이 필요함 -
이미지나 비디오를 표시할 수 있는 터미널을 찾고 있었음
단순히 브라우저처럼 동작하는 터미널이 있다면 좋겠음.
예를 들어browser google.com/maps처럼 명령으로 바로 인터랙티브하게 띄우는 식임- 하지만 이런 기능은 터미널이 아니라 별도 프로그램(fbi, omxplayer 등) 의 역할임
-
pseudo-terminal(PTY) 을 확장해 JSON-RPC 기반의 out-of-band 채널을 추가하자는 제안임
기존의 escape sequence는 한계가 많음.
이 방식이면 점진적이고 하위 호환적인 전환이 가능함.
LSP나 MCP처럼 기능 협상을 할 수 있고, 커널은 단순히 채널만 제공하면 됨- JSON은 이 용도로 부적절함. DER이나 SDSER 같은 바이너리 포맷이 더 효율적임
- 현대적인 접근은 사용자용 메시지는 stderr로, 기계 친화적 JSON은 stdout으로 보내는 것임
이렇게 하면 파이프라인과 리디렉션이 그대로 작동하고, 색상 출력도 유지됨