bash_history : 위험한 명령을 주석 처리하십시오 :`#`


16

bash 기록에서 "위험한"명령을 기록하지 않도록 .bashrc파일에 다음 줄을 추가했습니다 .

HISTIGNORE='rm *:mv *:cp *:cat*>*:pv*>*'

이것은 잘 작동하지만 부작용이 있습니다. 컴퓨터에서 실행 된 명령의 전체 기록을 볼 수 없습니다. 실험을위한 여러 머신이 있고 모든 명령이 실행되는 것을보고 싶습니다. bash internal history을 사용하여 실행 된 명령을 표시하고 오늘 날짜를 grep 할 수 있습니다.

history | grep Sep-28

내가하고 싶은 것은 "위험한"명령도 기록하지만 #줄의 시작 부분에를 넣어서 실수로 기록에서 명령을 실행하면 손상이 발생하지 않도록하는 것입니다.

이것이 가능한지 전혀 모른다.

업데이트 및 설명 :

이것이 나에게 문제가되는 주된 이유는 일반적으로 여러 터미널에서 내 컴퓨터에 연결되어 있고 한 터미널에서 실행 된 명령을 즉시 다른 터미널의 기록으로 읽기 때문입니다. 이것은 달성

PROMPT_COMMAND="history -a; history -c; history -r"

두 개의 터미널이 열려 있다고 상상해 봅시다. 하나에는 cat /dev/foo > file.out프로세스가 실행 중입니다. 두 번째로로 진행 상황을 확인합니다 ls -lAhF. 나는 반복 계속 ls눌러 UpENTER(역사이며, 마지막 명령). 곧 첫 번째 명령이 완료로, 역사에서 마지막 명령은 더 이상 없다 ls,하지만 cat /dev/foo > file.out. 주의하지 않으면 cat을 다시 시작하고 file.out을 덮어 씁니다.

내가 달성하고자하는 것은 cat 명령 앞에 #실행되지 않도록 cat 명령 앞에 오는 것입니다. 그러나 나는 여전히 그것을 역사에서보고 주석 처리를 취소하여 (긴 명령 인 경우) 재사용 할 수 있습니다.


명령을 수동으로 반복하는 대신 watch ls -lAhF또는 while sleep 1; do ls -lAhf; done; 파일 크기를 보는 대신 pv /dev/foo > file.out( ivarch.com/programs/pv.shtml )을 사용할 수 있습니다 .
deltab

답변:


9

당신은 다음과 같은 것을 할 수 있습니다 :

fixhist() {
   local cmd histnum
   cmd=$(HISTTIMEFORMAT=/ history 1)
   histnum=$((${cmd%%[*/]*}))
   cmd=${cmd#*/} # remove the histnum
   case $cmd in
     (rm\ *|mv\ *|...)
       history -d "$histnum" # delete
       history -s "#$cmd"    # add back with a #
   esac
}
PROMPT_COMMAND=fixhist

아이디어는 각 프롬프트 전에 마지막 기록 항목 ( history 1)을 확인하고 위험한 항목 중 하나 인 경우 삭제하고 ( history -d) with with로 다시 추가 한다는 아이디어 #입니다 history -s.

(분명히 HISTIGNORE설정 을 제거해야 합니다).

즉, 비록의 원치 않는 부작용은 변경이다 과거 시간 그 중 rm, mv... 명령.

이를 해결하기위한 대안은 다음과 같습니다.

fixhist() {
   local cmd time histnum
   cmd=$(HISTTIMEFORMAT='<%s>' history 1)
   histnum=$((${cmd%%[<*]*}))
   time=${cmd%%>*}
   time=${time#*<}
   cmd=${cmd#*>}
   case $cmd in
     (rm\ *|mv\ *|...)
       history -d "$histnum" # delete
       HISTFILE=/dev/stdin history -r <<EOF
#$time
#$cmd
EOF
   esac
}
PROMPT_COMMAND=fixhist

이번에는 마지막 히스토리 시간을 기록하고 히스토리 라인을 다시 추가하기 history -r위해 타임 스탬프가 포함 된 임시 파일 (여기 문서)에서 사용합니다.

fixhist앞에 수행 되기를 원합니다 history -a; history -c; history -r. 불행히도 현재 버전의 bash버그에는 history -a추가 한 줄을 저장하지 않는 버그가 있습니다. 해결 방법은 대신 작성하는 것입니다.

fixhist() {
   local cmd time histnum
   cmd=$(HISTTIMEFORMAT='<%s>' history 1)
   histnum=$((${cmd%%[<*]*}))
   time=${cmd%%>*}
   time=${time#*<}
   cmd=${cmd#*>}
   case $cmd in
     (rm\ *|mv\ *|...)
       history -d "$histnum" # delete
       history -a
       [ -f "$HISTFILE" ] && printf '#%s\n' "$time" "$cmd" >> "$HISTFILE";;
     (*)
       history -a
   esac
   history -c
   history -r
}
PROMPT_COMMAND=fixhist

즉, 주석 처리 된 명령을 HISTFILE 자체에 추가 history -a하지 않고 추가 해야합니다.


무엇을 설명 할 cmd=${cmd#*[0-9] }수 있습니까? 그리고 정확히 어디에 내가 넣어해야 fixhist내에서 PROMPT_COMMAND? 현재, 그것은 이미 포함되어 있습니다PROMPT_COMMAND="history -a; history -c; history -r"
Martin Vegter

의 역할은 HISTTIMEFORMAT=/무엇입니까? 나는 이미 설정했다 export HISTTIMEFORMAT="%b-%d %H:%M ". 그건 그렇고, 코드를 코드에 추가해도 $HOME/.bashrc아무런 변화가 없습니다.
Martin Vegter

HISTTIMEFORMAT=/cmd를 추출하기 쉬운 위치 history와 같은 출력을 얻는 한 번의 호출에만 해당됩니다 123 /rm x. 해당 컨텍스트에서 가짜 bash위치 $HISTCMD가 있는 일부 버전에 문제가 있었으므로 새 버전을 사용해보십시오.
Stéphane Chazelas

여전히 작동하지 않습니다. 궁금 #합니다. 코드에서 주석으로 작동하지 .bashrc않습니까?
Martin Vegter

1
수정 된 기록 항목의 경우 @MartinVegter 는 예상 기록 번호 뒤에 basha *를 삽입합니다 . 지금 수정해야합니다.
Stéphane Chazelas

11

귀하의 질문에 정확하게 대답하지는 않겠지 만 귀하의 문제에 대한 다른 해결책을 제시 할 것입니다.

내가 올바르게 이해한다면 입력과 관련하여 실수가 걱정되는 !rm경우입니다. 예를 들어 rm기록 의 이전 명령으로 유지하려는 항목이 제거 된 경우가 있습니다.

이 경우 좋은 bash 옵션은 histverify입니다. 당신이 경우 shopt -s histverify당신이 쾅하고 명령을 기억한다면, 그리고 !즉시 실행되지 않습니다,하지만 당신이 중 하나를 실행 여부를 결정할 수 있도록 readline에로드 할,이 또한 당신에게 편집 그에 대한 가능성을 제공합니다.

시도 해봐:

  • 없이 histverify:

    $ touch some_foo
    $ rm some_foo
    $ touch some_foo
    $ !rm
    rm some_foo
    $ # oooops in fact I'd've like to keep it this time
  • histverify:

    $ shopt -s histverify
    $ touch some_foo
    $ rm some_foo
    $ touch some_foo
    $ !rm
    $ rm some_foo <cursor here>

    이 경우 줄 끝에 커서를 놓거나 다시 시작하거나 편집 할 수 있습니다.

이 옵션이 마음에 드신다면 .bashrc:

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