"command_not_found_handle"을 로컬에서 재정의하는 방법은 무엇입니까?

"command_not_found_handle"을 로컬에서 재정의하는 방법은 무엇입니까?

일반적으로 친숙한 command_not_found 동작을 전역적으로 유지하면서 명령을 찾을 수 없을 때 특정 bash 스크립트가 빠르게 실패하도록 만들고 싶습니다. 예를 들어 다음을 에 저장하면 /tmp/foo.sh...

# ----------------------------start foo.sh----------------------------
THIS_FP="$0"
THIS_FN="$(basename ${THIS_FP})"
THIS_DIR="$(dirname ${THIS_FP})"

function setup {
  for CMD in \
    'foo' \
  ; do
    echo -e "\n$ ${THIS_FN}::${FUNCNAME[0]}::${CMD}"
    eval "${CMD}"
  done
} # end function setup

function teardown {
  for CMD in \
    "ls -alt ${THIS_DIR} | head" \
  ; do
    echo -e "\n$ ${THIS_FN}::${FUNCNAME[0]}::${CMD}"
    eval "${CMD}"
  done
} # end function teardown

for CMD in \
  'setup' \
  'teardown' \
; do
  echo -e "\n$ ${THIS_FN}::main loop::${CMD}"
  eval "${CMD}"
done
# ------------------------------end foo.sh----------------------------

...실행 가능하게 만든 다음 실행하면 얻을 수 있습니다.

# ----------------------------not what I want-------------------------
me@it:~$ /tmp/foo.sh 

$ foo.sh::main loop::setup

$ foo.sh::setup::foo
/tmp/foo.sh: line 10: foo: command not found

$ foo.sh::main loop::teardown

$ foo.sh::teardown::ls -alt /tmp | head
total 68840
drwxrwxrwt 22 root  root           1600 May  6 18:49 .
-rwxr-xr-x  1 me    me         527 May  6 18:49 foo.sh
drwx------  2 me    me          40 May  6 17:54 plugtmp-1
srw-------  1 me    me           0 May  6 17:28 tramp.13004aZf
drwx------  2 me    me        4200 May  6 17:22 matecorba-me
drwx------  2 me    me          40 May  6 02:20 plugtmp
-rw-------  1 me    me     2034335 May  4 14:21 s_TTRuhW.mp3.part
-rw-------  1 me    me     1658381 May  2 12:21 +rM4IttD.mp3.part
-rw-r--r--  1 me    me       86420 May  1 19:22 duplicity_20130501_1917.txt
# ----------------------------not what I want-------------------------

대신 내가 하고 싶은 건이 스크립트만foo.sh실패하고 "명령을 찾을 수 없음"이 발생하면 즉시 실패합니다.

# ------------------------------what I want---------------------------
me@it:~$ /tmp/foo.sh 

$ foo.sh::main loop::setup

$ foo.sh::setup::foo
/tmp/foo.sh: ERROR: foo: command not found

# Throwing me back to the shell from which I invoked foo.sh,
# *without* changing the usual friendly behavior outside it, e.g.:

me@it:~$ foo
No command 'foo' found, did you mean:
 Command 'fio' from package 'fio' (main)
 Command 'xoo' from package 'xoo' (main)
 Command 'fop' from package 'fop' (main)
 Command 'fox' from package 'objcryst-fox' (main)
 Command 'zoo' from package 'zoo' (main)
 Command 'goo' from package 'goo' (main)
foo: command not found
# ------------------------------what I want---------------------------

편집을 통해 이 동작을 제공할 수 있나요?오직 foo.sh.bashrc, 또는 현재 설치된 다른 파일을 건드리지 않았습니까 ? 그렇다면 어떻게 해야 할까요? 그렇지 않다면 왜 안 됩니까?

답변1

오류 발생 후 즉시 스크립트를 종료하려면 다음 명령을 사용하여 스크립트를 실행 bash -e /tmp/foo.sh하거나 스크립트 시작 부분에 다음 줄을 입력하세요 set -e.

-e또는 errexit"오류"가 발생하면 즉시 스크립트를 종료하도록 bash에 지시하십시오. 이 방법은 errexit그보다 조금 더 복잡하며 항상 예상대로 작동하지는 않습니다. 자세한 내용은 다음 문서를 읽어보세요.http://mywiki.wooledge.org/BashFAQ/105("왜 -e를 설정(또는 -o errexit 또는 트랩 ERR을 설정)하면 예상한 대로 작동하지 않습니까?")

bash 스크립트에서는 "명령을 찾을 수 없음" 처리가 (일반적으로) 활성화되지 않습니다. 이는 bash 스크립트가 bashrc를 읽지 않고 command_not_found_handle(보통) 일부 bashrc(예: debian /etc/bash.bashrc)에 정의되어 있기 때문입니다.

명령을 찾을 수 없음 처리가 스크립트에서 비활성화되어 있는지 확인하려면 다음과 같이 함수 정의를 해제하면 됩니다.

if [ x"$(type -t command_not_found_handle)" = x"function" ]; then
    unset -f command_not_found_handle
fi

bash 스크립트에서 이 작업을 수행하면구현하다대신에 스크립트구입, command_not_found_handlebash 스크립트에서만 정의되지 않습니다. 대화형 셸의 상태는 command_not_found_handle스크립트가 실행되기 전의 상태로 유지됩니다.

자세한 내용은 다음 문서를 읽어보세요.https://superuser.com/questions/176783/what-is-the-difference-Between-executing-a-bash-script-vs-commerce-it

그 동안 다음 내용 eval도 읽어보세요.http://mywiki.wooledge.org/BashFAQ/048("평가 명령 및 보안 문제")

관련 정보