본문 바로가기

별걸다하는 IT/리눅스 유닉스

[리눅스/LInux] history 명령어 및 옵션- 이전에 수행한 명령어 리스트 확인, 동작원리

반응형

[ LINUX / UNIX 완전정복 포스팅 링크 모음]

안녕하세요~! 방문자님들 오늘도 찾아주셔서 감사합니다.

오늘 알아볼 기초명령어는 history예요~!!

history 명령어 - 커맨드 이력 관리 명령어

자주 사용하는 명령어의 경우, 일일이 다시 치기 싫죠.

만약에 명령어를 반복적으로 돌아가면서 쳐야 한다고 했을 때, 메모장에 복사해서 보관한다 해도, 그거 매번 창 왔다갔다 하면서 컨트롤 브이 하는거 조차도 귀찮잖아요. 불러와서 알아서 쳐주면 좋겠다 생각할 수 있어요

 

또 내가 분명 썼던 커맨드인데 기억이 안난다, 뭔가를 쳐서 A결과가 나왔는데 뭘쳐서 A결과가 나온건지 기억이 안난다, 이전명령어랑 현재명령어랑 멀 다르게 쳐서 결과가 다르게 나왔는지 비교해보고 싶다.

내가 수행했던 이전 명령어들의 순서를 확인해보고 싶다든지!

이와 같은 상황처럼 명령어 이력을 보고 싶을 때 사용하는 명령어가 히스토리(history)입니다.

리눅스에서 man history 결과 

사용자로부터 명령창에 입력을 읽어들이는데, GNU에서 지원하는 history라는 라이브러리는 이러한 라인들 추적을 가능하게 해줍니다. 화살표 위아래 키를 왔다갔다 하면 전후 명령어들을 볼 수 있는데 이도 history덕분입니다.

history 명령어는 어떻게 지난 이력들을 기억할까? 

[히스토리 관련 환경변수] 

환경변수에는 HISTFILE, HISTSIZE, HISTFILESIZE 처럼 'HIST'라는 문자열로 시작하는 변수들이 있는데요. 얘네들이 다 history명령어와 관계가 있어요. history명령어 동작은 은근 단순합니다. 단순히 이전에 사용했던 명령어들의 리스트들을 파일에 저장해놨다가 보여주는 거예요.

history는 배시셸에서 지원하는데 (셸마다 지원여부가 달라요) bash의 경우, 해당 정보는 .bash_history에 저장됩니다. 요 파일 정보는 HISTFILE 환경변수를 보면 확인할 수 있어요. history는 유저별로 자신의 히스토리 파일을 가지고 있으며 홈 디렉터리에 숨김파일로 (.bash_history) 위치해있습니다.

실제로 해당 파일을 열어보면 이렇게 쳤던 명령어들이 나열되어 있는 것을 확인할 수 있습니다.

HISTFILESIZE는 말그대로 HISTFILE에 저장될 수 있는 최대 크기이고, HISTSIZE는 우리가 저장할 수 있는 명령어의 최대 개수예요. 즉 우리가 쳤던 명령어 1000개까지 history는 관리하고 있습니다.

HISTFILE : command 저장파일
HISTFILESIZE: 히스토리 파일 최대 크기
HISTSIZE: 히스토리에 저장 가능한 최대 명령어 개수 

[히스토리 동작 원리] 

파일에 명령어이력이 저장된다는건 알았어요. 그럼 명령어를 매번 shell에 칠때마다 저장되는 걸까요? 노노 그렇지 않습니다.

When you open a bash terminal, it loads the content of '~/.bash_history' and builds the active shell's history (in the RAM), adding every command executed in that shell to it - and olny to it, not to the file. Only when you close a bash terminal its history is appended to your '~./bash_history' file.

로그인 해서 bash 터미널에 들어가면, 파일의 내용을 로드해 RAM에 현재 active되어 있는 shell의 명령어 이력들을 저장할 그런 메모리공간을 만듭니다. (RAM에 저장되는 이걸 history list라고 부를거예요) 우리가 shell에 입력해 실행하는 모든 커맨드들은 파일에 저장되는게 아니라 여기 history list에 저장되는 거예요. 램에 저장된 명령어들은 bash shell이 종료될 때 '~./bash_history'파일에 추가 되는 방식으로 작동합니다.

로그인하고 shell이 시작되면, 아무 명령어도 안쳤으니까 history가 없어야할거같은데,

history 명령어를 쳐보면 결과가 잘 뜹니다. 파일에 있는 값을 읽어와서 history list에 불러오기 때문이예요. 

확인해보면 동일한 것을 알 수 있습니다.

history 옵션 OPTIONS

가장 중요한 건 사용법이죠. history에서 사용가능한 옵션들을 먼저 살펴봅시다.

옵션 의미
-c RAM에 있는 history list를 클리어 즉 삭제합니다. 
-d offset history 명령어 치면 첫 번째 열에 offset이 있는데 offset 위치에 있는 history 명령어를 삭제합니다.
-a history list에 있는 내용들을 파일에다가 추가합니다. (원래 종료될때 추가되는걸 지금 추가)
-n 히스토리 파일로부터 이미 읽혀지지 않은 라인들을 읽고 history list에다가 추가합니다. 
-r 히스토리 파일을 읽고 history list에다가 내용을 추가합니다.
-w 현재 history를 히스토리 파일에 씁니다. 

자세한 사용법은 아래에~ ㅎㅎ

사용 예시 examples

history 명령어 사용법 몇 가지를 대표로 들어볼게요.

1. history 명령어

history -c 는 history list를 깔끔하기 지워줍니다. 

확인하기 편하게 이전 명령어들 내역을 지웠어요. 그리고 echo hello1 부터 echo hello4 까지 명령어를 친 다음 history로 확인해봤습니다. 마지막으로 수행했던 'history'명령어를 포함해서 이전에 제가 실행했던 명령어들이 history list에 잘 저장된 것을 확인할 수 있어요.

 

history list에 저장된 가장 마지막 n개의 명령어를 보려면 'history n' 하시면 됩니다.

'history | tail -3'과 동일해요. (history 3 가장 최근에 사용한 3개 명령어) 

 

2. history -c

history -c 한다고 해서 히스토리 파일이 클리어되는게 아니랍니다. history list가 클리어되는 거예요.

실제로 $HISTFILE 내용을 보면, 우리가 쳤던 명령어들과 다른 명령어들이 저장된게 보여요.

마지막으로 친 명령어는 초록색라인인데 그 명령어도 안적혀있고, history -c라는 명령어도 안적혀있고 그 이후 명령어도 안적혀있죠? 이 파일이 업데이트 되는 순간은 종료시점이고 그 전까지는 RAM history list에 저장되기 때문이예요. 

 

3. history -d

history list offset, 599에 있는 'cleeeear' 명령어를 삭제! 확인해보니 화살표 부분에 원래 있었어야 했는데 삭제되어 없어진 것을 볼 수 있어요.

 

4. history -w 

history list를 별도의 파일로 저장하고 싶을 때 w옵션을 사용하면 가능합니다. (기존 데이터가 있으면 덮어씁니당)

history -w hist20200716

뒤에 파일명을 붙여주지 않으면 히스토리기본 파일에 덮어쓰기로 저장해요. 

 

5. !!

히스토리 사용에 확장되는 문자로 '!'가 있는데, '!!'를 입력하면 바로 직전에 실행한 커맨드를 실행합니다.

 

6. !n , !-n

같은 맥락으로 '!n'은 n번째에 저장된 명령어를 실행시켜요. history 로 n값을 확인 후 해당 커맨드를 실행시키고 싶으면 !n을 쳐주면 됩니다.

2번에 저장되어 있는 'echo add1'명령어를 실행해봤어요.

근데 이렇게 offset값을 지정해서 수행하는거 말고,

'내가 2번째 전에 쳤던 명령어, 3번째 전에 쳤던 명령어' 이런 방식으로 역순으로 명령어를 실행시키고 싶을 수 있겠죠. 그럴 때는 '-'를 붙여서 '!-n'을 치면 됩니다. 

두 번째 전에 친 명령어를 잘 불러오는 것을 확인할 수 있어요.

 

7. !string , !? string

string으로 시작하는 가장 최근에 실행한 커맨드를 찾아 실행시킵니다. 많이 쓰는 명령어예요.

느낌표(!)만으로 시작하는게 아니라 '!?'로 시작하면 string이 들어간 커맨드 중 최근꺼를 찾아서 실행시킵니다.

 

8. 실행말고 커맨드 출력만 (:p) 

그런데 어떤 커맨드인지 보여주지도 않고 검색후 바로 알아서 실행되는거면 좀 불안하죠. 실행까진 말고 커맨드만 체크하고 싶을 수 있어요. 그럴 경우 :p를 붙여주면 실행은 하지 않고 커맨드만 출력해줍니다. 

'!da'했을 때 가장 최근에 실행한 커맨드 중 'da'로 시작하는 명령어인 date를 실행시켜버리는 걸 볼 수 있어요 (초록박스)

하지만 '!da:p'를 쳐주면 'date'라는 커맨드라는것만 출력해주고 run하지 않는 것을 확인할 수 있습니다.

1. !da:p
2. !10:p
3. !-n4:p

이런식으로 뒤에 ':p'를 붙이면 됩니다.

결과

참고 (:p)는 !?에는 먹지 않아요. 

 

9. history 사용하고 싶지 않을때

내 이력 남기기 싫을때도 있는 법이죠. 그럴 때는 간단히 HISTSIZE 환경변수 값만 조정해주면 됩니다.

HISTSIZE는 히스토리에 저장 가능한 커맨드 개수로, 이 값을 0으로 지정하면 한 개도 저장할 수 없기 때문에 history 결과가 뜨지 않습니다. 

 

10. reverse-i-search

history에 몇백개의 명령어들이 있는데 그 중 어떤 커맨드를 찾고 싶다~~. 

'ctrl+r' 단축키를 누르면 reverse-i-search 모드로 들어가는데 여기다가 글자를 칠때마다 그에 부합하는 명령어를 하나씩 보여줍니다. 생각했던 커맨드가 나오면 엔터쳐서 실행시키면 돼요.

자 561라인에 있는 'echo world' 명령어를 실행시키고 싶어요. 히스토리에 저장된 명령어 개수가 총 641개인데, 561까지 뒤로가기 해서 찾으려면 위로가기 화살표키를 계속 쳐야겠죠. 다다ㅏ다ㅏ다..

위처럼 grep해서 특정 명령어 한정시킨 후 '!561' 명령어를 쳐서 접근할 수도 있겠지만,

만약 동일한 커맨드가 너무 많아서 grep결과가 많다던가.. 머 아무튼 작업이 한번에 안끝나니까 귀찮아요.

(reverse-i-search)`world': echo world //world를 치니까 echo world 명령어를 보여줌

이처럼 한번에 편리하게 찾고 싶을 때 ctrl+r을 눌러서 빠르게 찾아 실행시킬 수 있습니다.

 

오늘은 간단하게 bash 에서 지원하는 history 명령어에 대해 알아봤어요 

도움이 되었다면 공감 꾸욱. 정보공유에 큰 힘이 됩니다 :) 

다음에 또봐용~!

반응형