BASH 기록에서 성공적인 명령 만 유지


20

때로는 명령 구문을 오해합니다.

# mysql -d test
mysql: unknown option '-d'
# echo $?
2

다시 시도하고 올바르게 가져옵니다.

# mysql --database test
Welcome to the MySQL monitor.
mysql >
...

오류 코드가 0이 아닌 첫 번째 명령이 기록을 입력하지 못하게하려면 어떻게해야합니까?

답변:


20

나는 당신이 정말로 그것을 원한다고 생각하지 않습니다. 내 평소 작업 과정은 다음과 같습니다.

  • 명령을 입력하십시오
  • 그것을 실행
  • 실패했음을 주목하십시오
  • UP 키를 누릅니다
  • 명령 편집
  • 다시 실행

이제 실패한 명령이 기록에 저장되지 않으면 쉽게 수정하고 다시 실행할 수 없었습니다.


3
더 나은 디자인은 세션 기록과 영구 기록이 될 것입니다. 감사!
Adam Matan

터미널을 종료하면 기록이 저장됩니다. 따라서이 터미널 세션에서 입력 한 명령으로 돌아갈 수 있지만 실제로 터미널을 종료 할 때 bash 기록에 저장됩니다.
To Do

11

내가 이것을 생각할 수있는 유일한 방법은에서 사용하는 것 history -d입니다 $PROMPT_COMMAND. 이 방법이나 접근 방식의 문제점은 명령이 오류와 함께 종료되었거나 0이 아닌 종료 코드로 성공적으로 완료되었는지 알 수 없다는 것입니다.

$ grep non_existent_string from_file_that_exists
$ echo $?
1

4

수정하기 위해 마지막으로 잘못된 주석을 작성하는 것이 좋지만, 곧 혼란을 일으킬 수 있습니다.

내 접근 방식은 두 단계입니다. 명령이 실패하면 저장하고 나중에 제거하십시오.

실패 할 때 명령을 저장하십시오.

error_handler() {
    FAILED_COMMANDS="$(history | tail -1l | cut -c -5) $FAILED_COMMANDS"
}

trap error_handler ERR

trap command signalscommand중 하나 signals가 "일어 났을 때 " 실행합니다 .

$(command)을 실행 command하고 출력을 캡처합니다.

명령이 실패하면이 코드 스 니펫은 기록에 저장된 마지막 명령 의 기록 번호를 캡처합니다. 하고 나중에 삭제할 수 있도록 변수에 저장합니다.

간단한,하지만 함께 잘못 작동 HISTCONTROL하고 HISTIGNORE- 명령 인해 변수 중 하나에 역사에 저장되어 있지 않은 경우, 마지막 명령의 히스토리 번호는 역사에 저장 이전 명령의 하나이며, 따라서 잘못된 명령이 기록에 저장되지 않으면 이전 명령이 삭제됩니다.

이 경우에는 약간 더 복잡한 버전이 올바르게 작동합니다.

debug_handler() {
    LAST_COMMAND=$BASH_COMMAND;
}

error_handler() {
    local LAST_HISTORY_ENTRY=$(history | tail -1l)

    # if last command is in history (HISTCONTROL, HISTIGNORE)...
    if [ "$LAST_COMMAND" == "$(cut -d ' ' -f 2- <<< $LAST_HISTORY_ENTRY)" ]
    then
        # ...prepend it's history number into FAILED_COMMANDS,
        # marking the command for deletion.
        FAILED_COMMANDS="$(cut -d ' ' -f 1 <<< $LAST_HISTORY_ENTRY) $FAILED_COMMANDS"
    fi
}

trap error_handler ERR
trap debug_handler DEBUG

나중에 저장된 명령을 제거하십시오.

exit_handler() {
    for i in $(echo $FAILED_COMMANDS | tr ' ' '\n' | uniq)
    do
        history -d $i
    done
    FAILED_COMMANDS=
}

trap exit_handler EXIT

설명:

Bash를 종료 할 때 각 고유 기록 번호에 대해 해당 기록 항목을 제거한
다음 지우십시오.FAILED_COMMANDS 이미 삭제 된 명령에서 히스토리 번호를 상속 한 명령을 제거하지 않도록 지우십시오.

FAILED_COMMANDS중복이 없다고 확신한다면 간단하게 반복 할 수 있습니다
(예 : write for i in $FAILED_COMMANDS). 그러나, 당신이 (이 경우는 항상) 최대에서 최소로 분류되지 않을 것으로 예상하는 경우 교체 uniq와 함께 sort -rnu.

기록 번호는 FAILED_COMMANDS고유해야하며 최대에서 최소로 정렬되어야합니다. 항목을 삭제할 때 다음 명령의 번호가 이동하기 때문입니다. 발행 할 때history -d 2 하면 3 번째 항목이 2 위가되고 4 번째가 3 위가됩니다.

따라서이 코드를 사용할 때는 저장된 최대 숫자보다 작거나 같은 history -d <n>
위치를nFAILED_COMMANDS 수동으로 호출 할 수 없으며
코드가 제대로 작동 할 것으로 예상됩니다.

아마 훅하는 좋은 생각 exit_handlerEXIT,하지만 당신은 언제 이전을 호출 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.