GN⁺: 터미널에서 텍스트 입력의 복잡성
(jvns.ca)터미널에서 텍스트 입력이 복잡한 이유
- Mastodon에서 사람들이 터미널 작업에 대해 혼란스러워하는 점을 물어보았을 때, "이미 입력한 명령어를 편집하는 것"이 눈에 띄었음
- 터미널에서 텍스트 입력이 어려운 이유와 몇 가지 유용한 팁을 공유하고자 함
프로그램 간의 일관성 부족
- 다양한 프로그램이 텍스트 입력을 처리하는 방식이 일관되지 않음
- 일부 프로그램(
cat
,nc
,git commit --interactive
등)은 화살표 키를 전혀 지원하지 않음 - 많은 프로그램(
irb
,python3
등)은readline
라이브러리를 사용하여 기본 기능을 제공함 - 일부 프로그램은 기본적인 기능만 지원함
- 일부 프로그램은 완전히 커스텀된 입력 시스템을 가짐
- 일부 프로그램(
모드 1: 기본 상태
- 프로그램이 텍스트 입력을 단순히 받아들이는 기본 상태
- 텍스트 입력, 백스페이스,
Ctrl+W
,Ctrl+U
등의 기본 기능을 제공함 -
stty -a
명령어로 지원되는 모든 Ctrl 코드를 확인할 수 있음
- 텍스트 입력, 백스페이스,
모드 2: readline
을 사용하는 도구
-
readline
은 텍스트 입력을 더 편리하게 만드는 GNU 라이브러리-
Ctrl+E
,Ctrl+A
,Ctrl+left/right arrow
,Ctrl+R
등의 유용한 단축키를 제공함 -
bash
,psql
,irb
,python3
등 많은 프로그램이readline
을 사용함
-
팁: rlwrap
으로 readline
사용
-
rlwrap
을 사용하여readline
지원이 없는 프로그램도readline
기능을 사용할 수 있음
도구가 readline
을 사용하지 않는 이유
- 프로그램이 매우 단순하거나, 라이선스 문제, 상호작용이 적은 경우 등
readline
사용 여부 확인 방법
-
Ctrl+R
을 눌러reverse-i-search
가 표시되면readline
을 사용 중일 가능성이 높음
readline
키 바인딩의 기원
-
readline
키 바인딩은 Emacs에서 유래함
모드 3: 다른 입력 라이브러리 (libedit
등)
- Mac의
/usr/bin/python3
은libedit
을 사용하여 일부readline
기능만 지원함
모드 4: 커스텀 입력 시스템
-
nano
,micro
,vim
,emacs
등의 텍스트 편집기와fish
등의 쉘은 커스텀 입력 시스템을 가짐 - 커스텀 시스템은 종종
readline
에서 영감을 받음
많은 쉘이 vi 키 바인딩을 지원
-
bash
,zsh
,fish
등은 텍스트 입력을 위한 "vi 모드"를 지원함
상황을 이해하는 것이 도움이 됨
- 명령줄 프롬프트에서 텍스트를 입력할 때 상황을 이해하면 더 예측 가능하고 덜 혼란스러움
이 글에서 다루지 않은 내용
- ssh, tmux 관련 문제,
TERM
환경 변수, 다양한 터미널의 복사/붙여넣기 지원, 유니코드 등
GN⁺의 정리
- 터미널에서 텍스트 입력이 복잡한 이유와 다양한 프로그램 간의 일관성 부족을 설명함
-
readline
과 같은 라이브러리를 사용하여 텍스트 입력을 더 편리하게 만들 수 있는 방법을 제시함 -
rlwrap
을 사용하여readline
기능을 추가할 수 있는 팁을 제공함 - 터미널 사용 시 상황을 이해하는 것이 중요함을 강조함
Hacker News 의견
-
Julia의 글은 항상 좋음
- shell 스크립트에서
stty
를 사용해 터미널의 입력 처리 방식을 변경할 수 있음 - VT100 호환 터미널에서 키보드 조합과 마우스 제스처를 캡처하고 이해할 수 있는 실험을 공유함
-
bash -c "$(curl -L https://git.io/fjToH)"
명령어로 데모 실행 가능 -
vi | cat -v
를 사용해 인터랙티브 프로그램의 VT100 이스케이프 시퀀스를 볼 수 있음
- shell 스크립트에서
-
글에서 빠진 내용들
- 넓은 문자
- 키보드 모드에 따른 다른 ANSI 이스케이프 시퀀스
- 다양한 TTY 상태
- OS마다 다른 TTY 상태 변경 시스템 호출
- 터미널 에뮬레이션 지원의 차이
- 터미널 기능 확인 방법에 대한 합의 부족
-
bash에서 $EDITOR를 설정하면 ctrl-x ctrl-e로 현재 줄을 $EDITOR로 보낼 수 있음
-
20년 전 readline을 사용해 멀티라인 편집기를 만들었음
- 커서 이동과 터미널 크기 변경 시 재그리기 기능 포함
- Rust로 다시 작성하고 작은 라이브러리로 출시하고 싶음
-
fgets() 함수의 동작 방식에 대한 질문
- fgets()는 기본적으로 사용자가 새 줄을 입력할 때까지 블록됨
- 백스페이스, Ctrl+W, Ctrl+U 단축키를 사용해 줄 버퍼를 편집할 수 있음
-
터미널이 Linux의 시장 점유율을 낮추는 이유 중 하나라는 의견
- 터미널 사용 경험이 복잡함
-
dash shell이 화살표 키를 지원하지 않는다는 의견에 대한 반박
- libedit로 컴파일하면 편집 모드를 지원함
- POSIX 표준에서 "set -o vi"를 지원해야 함
-
사람들이 알면 유용할 기본 readline 키바인딩 세 가지
- Ctrl+W: 마지막 단어 삭제
- Ctrl+O: 히스토리에서 다음 줄 실행
- Ctrl+R: 히스토리에서 역방향 검색
-
Windows Terminal에서 Ctrl-C와 Ctrl-V의 동작 방식에 대한 불만
- Linux 터미널 앱이 Windows Terminal처럼 동작하지 않음
-
Linus의 클래식한 글을 상기시키는 의견