bash의 history는 -d 옵션을 지원합니다. -d 옵션은 특정한 줄을 삭제하는 것입니다. 그런데, -d 옵션을 분명히 썼는데, 다시 접속해 보면 기록이 남이 있는 이상한 상황을 경험하는 경우가 있어요. 왜 그런 것인지, 어떤 명령어를 써야 하는지 알아보도록 하겠습니다.
bash history 메모리와 파일
먼저 bash에서 history는 이 글 [링크] 에서 설명한 -d와 -c 말고도 몇 가지 명령이 더 있습니다.
- -w
- 현재 기록 목록을 기록 파일에 저장합니다.
- -c
- 모든 항목을 삭제하여, 기록 목록을 지웁니다.
이로 미루어 보았을 때, 기록 목록과 기록 파일은 다르게 돌아감을 알 수 있어요. 왜 이렇게 분리하는가? 생각해 보면 어렵지 않게 간파할 수 있습니다.1
먼저, history 명령어를 쳐 봅시다. 그러면, 1번부터 4번 명령어까지 결과에 나타납니다. 이를, “기록 목록” 이라고 합니다. 우리가 어떤 명령을 입력했는지 메모리에 기억해 두고 있는 것입니다.
그런데 cat $HISTFILE을 입력하면, 요래 나옵니다. 이는 왜 그런 것이냐면, history -w, history -w, exit 까지는 파일에 반영이 되었는데, 4번째 명령어인 history는 반영이 되지 않았기 때문입니다. 이 상황을 다시 도식화 해서 그려보겠습니다.
먼저 .bash_history에 아래와 같은 기록이 있었습니다. 그리고 새로 session 등을 열었을 때, 이 파일에 있었던 내용을 기반으로 메모리에 가져왔을 겁니다.
그러면, memory에도 이런 정보들이 올라갔을 겁니다. 어떤 정보가요?
- 내가 history -w를 2번 입력했고
- exit 명령어를 1번 입력했구나.
라는 정보가요. 이미 history 파일에 있던 것이 메모리에 올라갔기 때문에, 이 두 정보는 동기화가 되었을 겁니다.
그런데 우리는 history를 입력했습니다. 파일에 명령 기록을 쓴다는 옵션을 주지 않고 입력한 순간, 명령어 기록 목록에만 저장하게 됩니다. 여기서, sync 문제가 생기는 셈입니다. 게다가 우리는 HISTFILE에 저장된 명령어 목록을 보기 위해 cat $HISTFILE까지 입력했지요?
고로 이런 상황까지 가게 됩니다. memory에는 HISTFILE을 보는 5번 명령까지 있지만, 정작 history 파일에는 그런 것이 없다는 것입니다.
history의 -w 옵션
명령어 기록 파일을 기록 목록과 sync를 맞추면 어떨까요? bash history 에서는 -w 옵션이 이러한 역할을 합니다. 기록을 지웠는데 다시 재접속 해 보니, 히스토리가 남아 있는 문제를 해결할 수 있게 됩니다.
그림 3을 봅시다. -w 옵션으로 sync를 맞춘 후에, cat $HISTFILE 명령어를 다시 입력하였어요. 그러면 상황이 어떻게 될까요?
명령어 기록 파일에는 6번 command까지 올라갔어요. 그런가요? 이들을 히스토리를 기록하는 파일에 쓰게 됩니다. 저 6개의 명령어 목록이 그대로 반영이 되겠네요. 다음에, cat $HISTFILE 을 입력한 경우에는 어떤 결과가 나올까요?
6개의 명령어만 출력됩니다. 기록 파일에 6개의 명령을 저장한 이후에, cat $HISTFILE 명령을 입력했기 때문입니다.
정리해 보기
이제 이상한 상황이 왜 생겼는지 다시 정리해 봅시다.
저는 history -c로 기록을 모두 clear 하였습니다.
그런데 히스토리 기록은 다시 로그인 해 보니 그대로 남아 있네요? 어떻게 된 일일까요? 이것 역시 -w로 모두 clear 한 기록을 sync를 맞춰 주지 않아서 생긴 일입니다. 실제로, history 파일을 보면, 아래와 같은 내용들이 저장되어 있습니다.
즉, 기록의 변경 내용이, 파일에 반영이 되지 않았기 때문에, 이상한 상황이 발생한 것입니다. zsh의 경우도 명령어 기록 메모리와, 기록 파일이 따로 있습니다. 이 개념은 잘 알아두셔야 이상한 상황을 이해할 수 있습니다.
- 메모리보다 디스크에 쓰는 비용이 크기 때문입니다. ↩︎