Bash에서 histappend가 off로 설정된 경우 기록을 덮어쓰는 대신 추가하는 이유는 무엇입니까?

Bash에서 histappend가 off로 설정된 경우 기록을 덮어쓰는 대신 추가하는 이유는 무엇입니까?

며칠 전 ssh다른 터미널 탭이 로컬에서 많은 작업을 수행하는 동안 하나의 터미널 탭이 실행되었습니다. 그런 다음 (Mavericks가 설치된 Mac에서) 컴퓨터를 다시 시작했습니다.

터미널을 다시 실행해보니 두 번째 탭의 명령 기록이 모두 사라진 것을 발견했습니다. 주문 만 있습니다 ssh.

그래서 나는 어떻게든 기록을 "병합"하는 방법을 검색했고, 기록이 "덮어쓰기"가 아닌 추가되도록 파일 shopt -s histappend에서 작업을 수행해야 한다는 것을 알게 되었습니다 ~/.bashrc. 우리는 한 기록 세트가 다른 기록을 덮어쓰는 것을 원하지 않습니다. 추가하고 싶습니다.

그런데 shoptOS 에 histappend가보니 명령어를 쳐서 and 명령어를 봤습니다.echo abcecho defhistoryecho abcecho def

그런 다음 VirtualBox에서 Ubuntu 2014-10을 실행하고 비슷한 작업을 수행했지만 여전히 기록된 기록을 보았습니다( shopt -u histappend먼저 옵션을 끄기로 설정하기 위해 두 Bash를 모두 실행했습니다).

그렇다면 이 작업을 수행하는 메커니즘은 정확히 무엇입니까? 그렇다면 histappend켜거나 끄거나 상관없으면 아무 의미가 없나요?

shopt -s histappend또한 내 터미널을 주석 처리 .bashrc하고 다시 시작한 후 다시 시도했는데 두 탭이 결합될 수 있었던 기록을 봤습니다...참으로 이상한 동작입니다. 원인이 무엇일까요?

답변1

@대데이비드이 bash-help 스레드에 대해 말한 내용은 정확합니다.

여기bashC의 관련 코드입니다.

if (history_lines_this_session <= where_history () || force_append_history)
  {
    result = append_history (history_lines_this_session, hf);
    history_lines_in_file += history_lines_this_session;
  }
else
  {
    result = write_history (hf);
    history_lines_in_file = history_lines_this_session;
  }

shopt -s histappendforce_append_history0이 아닌 값( )으로 설정합니다 true.

history_lines_this_sessionbash이 대화형 세션에서 입력한 명령 수입니다. Bash를 처음 시작하면 0입니다. Enter기록에 저장된 각 명령에 대해 1씩 증가합니다.

where_history()인덱스 0부터 시작하는 메모리 내 기록 목록의 인덱스입니다. 기록에 기록될 다음 인덱스를 가리킵니다. 예를 들어 기록 레코드가 0개인 경우 인덱스는 0이 됩니다. 6줄의 히스토리가 있으면 인덱스 6이 됩니다.

처음 시작 하고 이력 이 bash있으면 증가하지만 제한됩니다 . 따라서 최대값이 있습니다 .HISTFILEwhere_history()<= HISTSIZEwhere_history()HISTSIZE

읽은 후에 는 증가하지만 HISTFILE여전히 0입니다. 명령 번호를 실행 하면 및 (최대 값이 있기 때문에). 이때 닫으면 기록이 덮어쓰기 됩니다.where_history()history_lines_this_sessionEnter HISTSIZE + 1history_lines_this_session == HISTSIZE + 1where_history() == HISTSIZE(history_lines_this_session <= where_history()) == falsehistappend

직접 테스트해 볼 수 있습니다 bash. 끄면 한 번 실행 한 명령 수가 1개를 histappend초과 하여 덮어쓰게 됩니다. 테스트가 작동하려면 다른 명령이 기록을 방해하지 않는지 확인해야 합니다(macOS에서 발생). 기록을 망칠 수 있는 명령을 끄려면 다음 명령을 사용하십시오.HISTSIZE + 1history_lines_this_sessionwhere_history()HISTFILE

trap - EXIT
PROMPT_COMMAND=
SHELL_SESSION_HISTORY=0 # for macOS only

답변2

histappend나는 이것이 다음을 위한 것이라고 믿는다하나단말기.

새 터미널에서 다음을 시도해 보세요.

shopt -s histappend
export HISTSIZE=1
export HISTFILESIZE=500

그런 다음 터미널을 닫습니다. 그러면 기록 파일에 export HISTFILESIZE=50방금 입력한 "" 와 함께 포함된 마지막 499개의 마지막 명령이 어떻게 포함되어 있는지 확인할 수 있습니다 . 기록이 추가된 후 500으로 잘렸습니다.

이제 다른 새 터미널에서 이것을 시도해 보세요.

shopt -u histappend
export HISTIZE=1
export HISTFILESIZE=500

터미널을 다시 닫습니다. 이제 터미널에 " export HISTFILESIZE=500"라는 명령이 하나만 있는 것을 볼 수 있습니다.

트릭은 그렇지 않은 경우 histappend현재 터미널 기록(명령)에 있는 내용으로 기록 파일을 덮어쓰게 된다는 것입니다.

HISTFILE= 인 경우 동작을 눈치채지 못할 것입니다 HISTFILESIZE. 하지만 여러 터미널에서 작업하는 것과는 아무 관련이 없다고 생각합니다. 이는 다른 것으로 관리해야 합니다...

관련 정보