command_not_found_handle
나는 잘못된 명령이 주어졌을 때 사용자에게 가장 동일한 명령을 의도한 것인지 묻는 나만의 함수를 만들려고 합니다 . 사용자가 제안을 수락하면 기록에서 마지막 명령(잘못된 명령)을 제거하고 선택한 명령을 추가해야 합니다. 하지만 작동하지 않습니다.
이게 내 코드야
command_not_found_handle(){
....
# replace the previous wrong command with the correct one in bash history
history -d -1
history -s "$command $@"
}
잘못된 명령을 입력하고 제안 사항 중 하나를 선택하면 기록이 수정되지 않습니다. 하지만 내가 직접 함수를 호출하면
command_not_found_handle wrong_command
기록을 업데이트하고 기록을 삭제하며 wrong_command
새 기록을 추가합니다.
history
함수 내에서 명령(기록 목록을 반환함)을 호출하여 두 경우 모두 함수에 기록에 대한 읽기 액세스 권한이 있는지 확인했습니다. 그러나 첫 번째 경우에는 역사에 기록될 수 없습니다.
답변1
이 기능을 직접적으로 사용하는 것은 불가능해 보입니다 command_not_found_handle
.
에 따르면 man bash
:
검색에 실패하면 쉘은 command_not_found_handle이라는 정의된 쉘 함수를 검색합니다. 함수가 존재하는 경우 원래 명령과 원래 명령의 인수를 인수로 사용하여 별도의 실행 환경에서 호출됩니다.
history
따라서 모든 변경 사항 등이 variables
손실됩니다. 예를 들어 다음을 다음 항목에 포함하세요 ~/.bashrc
.
val=10
command_not_found_handle() {
echo Val is $val
val=50
echo Val now is $val
}
존재하지 않는 명령을 실행하기 전에 다음 값을 인쇄해 보아야 합니다 val
.
(bash shell)> echo $val
#Output
10
ls4
이제 존재하지 않는 명령(예 : 인쇄) 을 입력하면 val
다음과 같은 결과를 얻게 됩니다.
(bash shell)> ls4
#Output
Val is 10
Val now is 50
(bash shell)> echo $val
#Output
10
위에서 볼 수 있듯이 최종 값은 이지만 50
완료 후 command_not_found_handle
최종 값은 입니다 10
.
이는 기본적으로 서브쉘을 실행하고 있기 때문에 발생합니다 bash
. 다음을 사용하여 확인할 수 있습니다.
val=10
command_not_found_handle() {
echo Val is $val
val=50
echo Val now is $val
echo "Parent bash PID: $$"
echo "BASH PID: $BASHPID"
#echo $BASH_SUBSHELL #NOTE If I'm not wrong this should print `1` but
# it prints 0 (which is the current level of the bash parent shell). I'm not sure why.
echo -e "\nUsing ps\n"
ps
}
존재하지 않는 명령을 실행하면 다음과 같은 결과가 다시 나타납니다.
(bash shell)> ls4
#Output
Val is 10
Val now is 50
Parent bash PID: 15399
BASH PID: 15420
Using ps
PID TTY TIME CMD
10561 pts/3 00:00:00 zsh
15399 pts/3 00:00:00 bash
15420 pts/3 00:00:00 bash
15421 pts/3 00:00:00 ps
보시다시피 command_not_found_handle
쉘에서 실행 중입니다 PID: 15420
. 따라서 변수는 완료 시 val
해당 값을 잃습니다 .50
command_not_found_handle
가능한 해결책:
너는 저장해야 해옳은이 명령은 파일에 쓰고 다음 세 가지 방법 중 하나로 기록을 수정합니다.
함수 command_not_found_handle
는 다음과 같아야 합니다.
command_not_found_handle() {
echo "$1: command not found" >&2
read -p "What did you mean? " cmd
echo -n "$cmd" > '/tmp/cmd.txt'
}
이제 기록을 수정하는 함수를 만들어야 합니다.
checkHist(){
[ -f '/tmp/cmd.txt' ] && {
h="$(cat /tmp/cmd.txt)"
history -d -1
history -s "$h"
rm '/tmp/cmd.txt'
}
}
마지막으로 다음 세 가지 옵션을 사용하여 기록을 쉽게 수정할 수 있습니다.
해결 방법 1:변수 사용 PROMPT_COMMAND
:
PROMPT_COMMAND='checkHist'
위 코드를 사용하면 명령어가 실행될 때 내부의 내용 (이 경우에는 함수)이 PROMPT_COMMAND
실행됩니다 . checkHist
자동으로 수행되므로 이것이 가장 쉬운 방법입니다.
해결 방법 2:바인딩 키/단축키
bind -x '"\C-p":checkHis'
위의 코드를 사용하여 checkHis
다음 명령을 누르면 함수가 실행됩니다.Ctrl+p
해결 방법 3:짧은 별칭 사용
alias u="checkHist"
u
이 별칭을 사용하면 터미널에서 해당 문자를 사용/입력하여 기록을 수정할 수 있습니다.