피할 수 없다: ANSI 코드 탐구
출처: Hacker News
2025년 12월 22일 · 읽는 데 4분 · 작성자: Safia Abdalla
ANSI 이스케이프 코드는 꽤 미친 듯이 매력적이지 않나요? 말 그대로 미친 건, 그 개념이 너무 단순하면서도 오랫동안 살아남았다는 점이에요. 터미널이 굵은 빨간색 텍스트를 표시하거나 진행 바가 화면을 가로질러 움직일 때마다, 우리는 거의 50년 된 표준을 활용하고 있는 겁니다. 저는 컴퓨터 역사를 깊게 파고드는 편은 아니지만, 이런 표준을 이해하고 감탄하면 우리 산업에 대한 애정이 커지고, 오늘 우리가 만들고 있는 표준이 앞으로 50년간 어떻게 확장될지에 대한 감을 잡을 수 있을 거라 생각합니다. 그럼, ANSI 이스케이프 코드의 세계로 들어가 보죠.
작동 원리
제가 지구에 존재하기 전, 터미널은 물리적인 장치였습니다. 메인프레임에 직렬 케이블로 연결된 CRT 모니터였죠. 이런 “덤 터미널”은 텍스트를 표시할 수 있었지만, 그 정도가 전부였습니다. ANSI 이스케이프 코드를 정리한 표준은 바로 이런 매체의 한계에 대한 반응으로 탄생했습니다. 당시 사용할 수 있는 전송 형식은 순수 텍스트뿐이었고, 터미널은 텍스트 스트림을 문자 하나씩 처리할 수밖에 없었습니다. 표준은 텍스트 스트림에 추가적인 동작을 인코딩할 수 있는 형식을 정의했으며, 여기에는 커서 위치 제어, 텍스트 서식 지정, 색상 지정 등이 포함되었습니다.
터미널은 특수 문자 시퀀스를 포함할 수 있는 텍스트 스트림을 소비합니다. 현대 터미널 에뮬레이터는 스트림을 문자 단위로 읽으며, 이스케이프 시퀀스를 만나면 이를 화면에 표시하는 것이 아니라 명령으로 해석합니다.
ANSI 이스케이프 시퀀스는 ESC 문자(ASCII 27, 혹은 16진수 \x1b) 뒤에 왼쪽 대괄호 [가 붙은 형태로 시작합니다. 이를 Control Sequence Introducer (CSI) 라고 부릅니다. 그 뒤에 실제 명령이 따라옵니다. 예를 들어:
\x1b[31m→ 텍스트 색상을 빨강으로 설정\x1b[1m→ 텍스트를 굵게(bold) 표시\x1b[0m→ 모든 서식 초기화\x1b[2J→ 화면 전체를 지움\x1b[H→ 커서를 좌상단으로 이동
여러 속성을 동시에 지정하려면 세미콜론으로 구분하면 됩니다. 따라서 \x1b[1;31m 은 굵은 빨강 텍스트를 만들죠. 마지막에 붙는 m 은 Select Graphic Rendition (SGR) 명령으로, 모든 스타일링을 담당합니다.
원래 사양은 8가지 색상(검정, 빨강, 초록, 노랑, 파랑, 마젠타, 시안, 흰색)만 정의했지만, 현대 터미널은 이를 크게 확장했습니다. 256색 모드는 \x1b[38;5;208m 같은 코드를 사용해 확장 색상을 지정합니다. 진짜 24비트 컬러는 \x1b[38;2;255;128;0m 와 같이 RGB 값을 직접 넣어 표현합니다.
왜 중요한가
1979년에 만든 표준이 오늘날 CLI와 상호작용하는 방식의 근간을 이루고 있습니다. 명령 실행 시 색이 입힌 출력이나 진행 표시줄을 보면, 바로 ANSI 코드가 작동하고 있는 겁니다. 쉘 프롬프트를 커스텀해서 배경·전경 색을 바꿨다면, 역시 이 ANSI 코드를 활용한 것입니다.
ANSI 코드는 그만큼 오래 살아남은 표준이라 현대적인 리프레시도 받았습니다. .NET의 Spectre.Console이나 Node의 chalk 같은 패키지는 애플리케이션에서 ANSI 코드를 쉽게 다룰 수 있는 헬퍼를 제공합니다. 이들 패키지는 1979년 당시와 비교해도 꽤 정교한 스피너·바운서 렌더링 패턴을 제공하는데, 커서 이동과 재작성(overwrite)을 이용해 화면을 실시간으로 바꾸는 방식이죠. aspire deploy 명령을 써본 적이 있다면, 이런 패턴을 조합해 꽤 화려하고 인터랙티브한 UI를 만들 수 있다는 걸 알 수 있을 겁니다. 자세한 내용은 내가 이전에 쓴 글을 참고하세요.
Vim이나 htop 같은 좀 더 고급 터미널 UI는 ANSI 코드를 확장해 커서 위치 지정·화면 조작을 전면에 내세워 전체 화면 인터랙티브 경험을 제공합니다. 예를 들어 \x1b[10;20H 는 커서를 10번째 행, 20번째 열로 이동시키라는 의미입니다. 라인을 지우고 문자를 그리는 기능과 결합하면, 텍스트 스트림만으로도 놀라울 정도로 복잡한 인터페이스를 만들 수 있습니다.
직접 해보기
아래에 간단한 인터랙티브 위젯을 만들었습니다. 여기서 다양한 이스케이프 시퀀스를 실험해 보면 실시간으로 어떻게 렌더링되는지 확인할 수 있습니다. 글꼴 스타일, 전경·배경 색, 커서 이동이 각각 어떤 ANSI 코드를 만들어 내는지 직접 확인해 보세요.
다음에 터미널 출력이 화려하게 보일 때면, 그 뒤에 어떤 주문이 숨어 있는지 정확히 알 수 있을 겁니다.
P.S. 이 블로그 글은 위의 작은 인터랙티브 UI를 보여주기 위한 변명 같은 글이기도 합니다. 연속 백엔드 악당(두운과 말장난? 현실감 없죠!)으로서, 작은 학습용 인터랙션을 만들면서 디자인 감각을 키우고 싶었습니다. 이 작업을 하면서 Tailwind를 처음 써봤고, 꽤 재미있었어요. 솔직히 말하면 코딩은 대부분 AI가 해냈고, 제가 한 일은 주로 경험이 어떻게 보여야 할지 구상하는 정도였습니다. 혹시 이 UI가 “텍스트만 보는 사람”이 만든 것처럼 보인다면 알려 주세요.