bash 명령어 히스토리 관리 - readline 사용법 및 line 편집, reverse search 등 단축키 요약
유튜브에 동영상 강의를 올렸으니 참고하세요.
TL;DR
readline 을 잘 사용하면 커맨드 라인 생산성을 높이고 실수를 최소화할 수 있습니다.
많은 기능중에 자주 쓰이는 다음 단축키들은 잘 익혀둘 필요가 있습니다.
단축키 | 용도 |
---|---|
Ctrl-a | 라인 시작 |
Ctrl-e | 라인 끝 |
Ctrl-k | 라인 삭제 |
Ctrl-r | 역 점진 검색 |
Esc-d | 단어 삭제 |
개요
예전에는 HP-UX, Solaris, AIX 등 다양한 Unix 가 업무에 사용되었고 리눅스는 장난감정도의 취급밖에는 받지 못했습니다.
그 당시에 제가 새로운 유닉스 시스템을 사용하게 되면 제일 처음에 했던 작업은 bash 와 vim 설치였습니다.
유닉스의 기본 쉘인 sh 나 csh 에 비해 bash 의 장점은 무지 많지만 그중에 line-editing 이나 커맨드로 예전 명령어를 불러내는 history 기능은 명령행 작업의 편리성과 생산성을 극대화시키고 실수를 최소화 해주는 기능입니다.
이런 bash의 편리한 command line 능력은 엄청난 인기를 얻어서 아예 readline library 라는 별도의 library 로 분리되었으므로 command line 으로 동작하는 program 을 만들 일이 있을 경우 사용하면 사용자 편의성을 높일수 있습니다.
readline 라이브러리를 사용하는 유명한 프로그램으로는 MySQL 이나 MariaDB 에 내장된 command line client 인 mysql 명령어가 있습니다.
$ mysql --version mysql Ver 15.1 Distrib 10.1.41-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2
readline 의 주요 기능
명령어 history 호출
위 아래 화살표 키를 이용하여 최근에 사용했던 명령어 목록을 불러올 수 있습니다. 만약 쉘상에 상세 단어가 입력되어 있다면 해당 단어로 시작하는 명령어만 호출됩니다.
history 명령어
bash 의 내장 명령어로 옵션없이 실행하면 실행한 모든 history 의 목록을 표시합니다.
history 내역은 쉘의 HISTFILE 환경 변수에 지정된 경로에 저장하며 지정되지 않았을 경우 ${HOME}/.bash_history 에 저장합니다.
명령어 | 의미 | 사용예 |
---|---|---|
history -c | history 목록을 모두 지운다. | |
history -d offset | offset 으로 주어진 history 목록의 명령어를 지운다. | history -d 3 |
history -w | 현재 shell 의 history 를 history 파일 에 저장한다. 예전 history 데이타는 덮어쓴다. |
주요 단축키 목록
Key | action | 비고 |
---|---|---|
\C-a | line 의 처음으로 가기 | |
\C-e | line 의 끝으로 가기 | |
\C-l | clear screen | |
\C-k | kill line | 라인 전체 삭제(\C-a 로 라인의 처음으로 가야 함) |
\C-p | 예전 history로 가기 | 화살표의 ↑ 동일 ("\e[A") |
\C-n | 다음 history로 가기 | 화살표의 ↓동일("\e[B") |
\C-r | reverse search history | 예전에 사용했던 명령어를 가장 오래된 명령어부터 검색(increment search) |
\C-s | forward search history | 예전에 사용했던 명령어를 가장 최근 명령어부터 검색(increment search). 터미널의 STOP 문자와 충돌하므로 하단의 i-search 항목을 참고하여 수정 |
\e-u | line의 문자를 대문자로 변경 | |
\e-l | line의 문자를 소문자로 변경 | |
\C-w | 이전 단어 삭제 | |
\C-s | reverse incremental search | |
\C-g | reverse incremental search 중지 |
예전/다음 히스토리 단축키인 Ctrl-p/Ctrl-n 은 쉘 상에 Ctrl-n 이나 아래 화살표(↓)는 다음 history 로 이동하게 된다.
readline 활용
이전 명령어 재활용
다음과 같이 현재 디렉터리에서 파이썬 소스와 html 파일의 목록을 찾는 명령어가 있을 경우 찾는 경로를 현재 경로인 . 에서 /var/www 로 변경한다고 생각해 봅시다.
이럴 경우 화살표 키로 예전 명령어를 누른 후에 Ctrl-a 를 눌러서 라인의 첫 줄로 간 후에 . 을 /var/www 로 수정하면 됩니다.
find . \( -name "*.py" -o -name "*.html" \)
만약 찾는 경로를 수정하고 찾는 파일 형식에 css 를 추가한다면 경로 수정후 Ctrl-e 를 눌러서 마지막 라인으로 간 후에 수정하면 됩니다.
역 점진적 검색
예전에 사용했던 명령어를 재호출할때 보통 화살표키를 눌러서 찾는 명령어가 나올때까지 history 를 조회합니다.
명령어 히스토리가 몇 개 없다면 괜찮지만 많을 경우 불편하므로 이런 경우 역 점진적 검색(reverse incremental search) 를 사용하면 됩니다.
다음 예를 보면 이해가 될 겁니다.
- 현재 history 에 100개의 목록이 등록되어 있음
- 찾고자 하는 명령어는 54번째에 있으며 해당 명령어는 find . -name \*.xml
- 화살표 키를 이용하면 54번을 눌러야 한다.
Ctrl-r 키를 눌러서 다음과 같이 Reverse-i-search 모드로 들어간다. (Prompt 가 없어지고 아래와 같이 입력창이 뜬다.
(reverse-i-search)`':
incremental search 이므로 한 글자를 입력할때 마다 해당하는 명령어를 보여줌
(reverse-i-search)`fi': find . -name \*xml
- 호출하고자 하는 명령어가 나올때까지 예전 명령어를 입력후 나왔으면 엔터를 쳐서 찾은 명령어를 수행
점진적 탐색
위와 반대로 Ctrl-s 를 누르면 history 에서 forward increment search 를 수행할수 있습니다. 가끔 터미널의 STOP 키와 충돌하여 동작하지 않는 경우가 있으니 (stty -a 로 확인 가능)
readlne 의 기본 키인 Ctrl-s 를 동작하게 하려면 터미널에서 다음 명령을 수행합니다.
$ stty stop ''
또는 bash 의 로그인 설정(.bash_profile) 파일에 위 내용을 추가합니다.
http://vaab.blog.kal.fr/2010/11/11/enabling-ctrl-s-for-forward-history-search-in-bash/ 참고
readline 동작 설정
고급 내용이므로 건너뛰어도 됩니다.
설정 파일
readline 은 동작에 관한 설정을 $HOME/.inputrc 파일에 지정하고 있으며 # 으로 시작하는 라인은 comments 로 처리되며 설정은 다음과 같은 형식을 따릅니다.
$ set variable value
bash 에서 readline 관련 현재 설정을 확인하려면 bind -V 명령어를 수행하면 됩니다.
root@centos7:~:> bind -V bind-tty-special-chars is set to `on' blink-matching-paren is set to `on' byte-oriented is set to `off' completion-ignore-case is set to `off' convert-meta is set to `off' ...
Key Binding
readline 에서 사용하는 key binding 은 bind -p 옵션으로 확인할수 있습니다.
root@centos7:~:> bind -p "\C-a": beginning-of-line "\C-x)": end-kbd-macro "\e>": end-of-history "\C-e": end-of-line "\eOF": end-of-line "\e[4~": end-of-line "\e[8~": end-of-line "\e[F": end-of-line ...
libedit 는 무엇인가?
GNU readline 은 커맨드 라인 작업시 탁월한 생산성을 제공하는 훌륭한 제품입니다. 이때문에 GNU 에서는 GPL(GNU Public License)가 확산되기를 바랬고 readline library 를 일반적인 라이브러리의 라이선스인 LGPL 과 달리 GPL 로 제공합니다.
이때문에 GPL 이 아닌 프로그램은 readline 을 사용할수 없습니다.
그래서 GPL 이 아닌 운영체제인 NetBSD 에서는 readline 과 API 가 호환되는 라이브러리를 만들었고 이게 libedit 입니다.
프로그램 라이센스가 GPL 이 아닌 데 readline 기능을 제공하고 싶을 경우 libedit 를 사용하면 됩니다.
같이 보기
참고 자료
- bash Command Line Editing - http://www.gnu.org/software/bash/manual/html_node/Command-Line-Editing.html
- Using History Interactively - http://www.gnu.org/software/bash/manual/html_node/Using-History-Interactively.html
- http://readline.kablamo.org/emacs.html
- Bash Cheat Sheet Updated for 2022 - from Basics to Shell Builtins (pcwdld.com)