zsh 기록에서 마지막 명령(또는 보너스를 위한 현재 명령)을 제거하는 방법

zsh 기록에서 마지막 명령(또는 보너스를 위한 현재 명령)을 제거하는 방법

물론 이를 수행하는 매우 간단하고 현명한 방법이 있지만 zshell의 기록은 fc의 별칭인 것 같으므로기록에서 줄을 삭제하는 방법은 무엇입니까?.

이 작업을 수행하는 방법에 대한 조언이 있습니까? 내 사용 사례는 기록에서 실행된 마지막 명령을 제거하여 자동 완성을 중지하는 것입니다(주로 잘못된 내용을 입력하고 계속 표시되는 경우).

다음을 수행하여 마지막 명령을 내릴 수 있다는 것을 알고 있습니다.

history | tail -n 1, 그러나 History -d가 작동하지 않고 zsh에 대한 올바른 문서를 찾을 수 없습니다.

답변1

Zsh는 진정한 기록 편집 기능을 제공하지 않습니다. 명령 기록은 기본적으로 읽기 전용입니다. 당신이 할 수있는 일은 그것을 도매로 교체하는 것뿐입니다.

명령 기록 편집:

  1. 파일에 저장합니다.fc -W
  2. 파일 편집
  3. 파일에서 기록 로드:fc -R

설정을 통해 파일 이름을 선택할 수 있습니다 HISTFILE.

테스트되지 않은 코드:

remove_last_history_entry () {
  setopt local_options extended_history no_hist_save_no_dups err_return
  
  local HISTFILE=~/.zsh_history_tmp_$$ SAVEHIST=$HISTSIZE
  fc -W
  ed -s $HISTFILE <<EOF >/dev/null
d
w
q
EOF
  fc -R
}

답변2

일반적으로 줄을 삭제할 수 있지만 ~/.zsh_history찾을 수 없는 경우 ~/.zshrc기록 파일의 위치를 ​​찾아보세요.

그런 다음 원하는 텍스트 편집기를 사용하여 문제가 있는 줄을 삭제하십시오. 또는 전체 파일을 삭제하고 모든 zsh 인스턴스를 닫고 새 인스턴스를 시작하십시오. 역사는 말끔히 지워진다!

답변3

예, 이것은 오래된 주제이지만 이러한 질문 중 어느 것도 내 질문에 대한 답변이 아니기 때문에 이것을 알아내려고 오랜 시간을 보냈습니다!

내 솔루션은 다음과 같습니다. @Gilles에게 감사드립니다."fc -R" 및 "fc -W" 사용에 대한 팁 :).

아래 스크립트를 .zshrc 파일에 붙여넣으세요.

source.zshrc를 사용하여 다시 로드

그런 다음 "forget"을 입력하고 마지막 명령을 잊어버리세요. :D. 마지막 3개의 명령을 잊어버리려면 "forget 3"을 입력하세요. 섹시한 지글지글.

위쪽 화살표를 누르면 마지막 명령으로 바로 이동하며 "forget"이라는 단어도 기억되지 않습니다. :).

고쳐 쓰다:이제 모든 디렉토리에서 작동하도록 기본 경로를 추가했습니다. 하하.

업데이트 2:잊어버리고 싶은 마지막 명령의 개수를 전달하는 기능이 추가되었습니다 :D. 마지막 2개의 명령을 잊어버리려면 "forget2"를 시도해 보세요. :D.

# Put a space at the start of a command to make sure it doesn't get added to the history.
setopt histignorespace

alias forget=' my_remove_last_history_entry' # Added a space in 'my_remove_last_history_entry' so that zsh forgets the 'forget' command :).

# ZSH's history is different from bash,
# so here's my fucntion to remove
# the last item from history.
my_remove_last_history_entry() {
    # This sub-function checks if the argument passed is a number.
    # Thanks to @yabt on stackoverflow for this :).
    is_int() ( return $(test "$@" -eq "$@" > /dev/null 2>&1); )

    # Set history file's location
    history_file="${HOME}/.zsh_history"
    history_temp_file="${history_file}.tmp"
    line_cout=$(wc -l $history_file)

    # Check if the user passed a number,
    # so we can delete x lines from history.
    lines_to_remove=1
    if [ $# -eq 0 ]; then
        # No arguments supplied, so set to one.
        lines_to_remove=1
    else
        # An argument passed. Check if it's a number.
        if $(is_int "${1}"); then
            lines_to_remove="$1"
        else
            echo "Unknown argument passed. Exiting..."
            return
        fi
    fi

    # Make the number negative, since head -n needs to be negative.
    lines_to_remove="-${lines_to_remove}"

    fc -W # write current shell's history to the history file.

    # Get the files contents minus the last entry(head -n -1 does that)
    #cat $history_file | head -n -1 &> $history_temp_file
    cat $history_file | head -n "${lines_to_remove}" &> $history_temp_file
    mv "$history_temp_file" "$history_file"

    fc -R # read history file.
}

여기서 뭔가 일어나고 있습니다. 이 명령을 사용하면 명령 앞에 공백을 입력할 수 있으며 기록에 추가되지 않습니다.

setopt histignorespace

따라서 스페이스 바를 누른 다음 "echo hi"를 입력하고 Enter 키를 누른 다음 위쪽 화살표를 누르면 "echo hi"가 기록에 없습니다. :)

별칭 "forget"에는 my_remove_last_history_entry 앞에 공백이 있습니다. 이런 식으로 zsh는 "망각"을 기록에 저장하지 않습니다.

기능 설명

ZSH는 fc를 사용하여 기록이나 기타 항목을 기록하므로 "fc -W"를 사용하여 현재 명령을 기록 파일에 기록한 다음 "head -n -1"을 사용하여 파일에서 마지막 명령을 제거합니다. 이 출력을 임시 파일에 저장한 다음 원래 기록 파일을 임시 파일로 바꿉니다. 마지막으로 fc -R을 사용하여 기록을 다시 로드합니다.

그런데 이 함수에 문제가 있었는데, 이는 앨리어싱으로 해결되었습니다.

이름으로 함수를 실행하면 함수 호출인 마지막 명령이 제거됩니다. 그렇기 때문에 zsh가 이 함수 이름을 기록 파일에 추가하지 않도록 별칭을 사용하고 공백으로 호출하여 마지막 항목을 우리가 원하는 항목으로 만듭니다. :D.

답변4

@pandagoespoop의 단순화된 버전을 사용합니다. 답변, 그것은 나에게 잘 작동합니다 (제한: Linux에서는 한 줄 명령의 경우).

한 가지 중요한 수정 사항은 새로 생성된 기록 파일에 대한 권한을 제한하는 것입니다. 기본 권한이 있는 새 파일로 리디렉션하면 그룹과 다른 사람들이 기록을 읽을 수 있습니다. 그래서 나는 다음과 같이 덧붙였습니다.

chmod 600 $history_temp_file

전체 코드:

setopt hist_ignore_space

alias forget=" forget_last_history_entry"
forget_last_history_entry() {
    history_file="${HISTFILE:-${HOME}/.zsh_history}"
    history_temp_file="${history_file}.tmp"

    fc -W # write current shell's history to the history file.

    # Get the files contents minus the last entry(head -n -1 does that)
    head -n -1 $history_file > $history_temp_file
    chmod 600 $history_temp_file
    mv "$history_temp_file" "$history_file"

    fc -R # read history file.
}

내가 그런 평판을 얻었다면 나는 논평했을 것이다.

관련 정보