Bash
bash/zsh 掛鉤 - 僅在未找到匹配文件時才添加到 PATH
我正在尋找一個 bash/zsh鉤子,當找不到命令時呼叫它。
假設我執行一些任意執行檔:
xyz foo --bar
- 說 bash/zsh 找不到執行檔。
- 有沒有辦法處理“未找到”,然後將一些庫動態載入到 PATH 中?
像這樣的東西:
function xyz { if ! test -f xyz; then load_libs xyz fi command -v xyz; }
類似這個函式的東西,但它適用於未知的執行檔。
所以一般來說它看起來像:
function on_not_found { if ! test -f "$1"; then load_libs "$1" fi command -v "$@"; }
兩者都
zsh
具有bash
掛鉤函式,您可以定義這些函式來處理找不到命令的情況。它被稱為command_not_found_handle
inbash
和command_not_found_handler
inzsh
(受bash
’s 啟發,但錯字/誤稱已修復)。但是請注意,它們在子程序中執行(更不用說子shell 可能找不到該命令),因此無法更改您的shell 環境。
你可以這樣做:
zsh
command_not_found_handler() { { if (( ! IN_CNFH++)) && load_lib "$1"; then "$@" else print -ru2 -- "$functrace[1]: command not found: $1" return 127 fi } always { (( IN_CNFH-- )) } }
IN_CNFH
如果命令成功後仍然找不到,避免無限遞歸的部分load_lib
。如果您已經有一個
command_not_found_handler
(某些系統在其 zsh 預設配置中提供了一個,以在找不到命令時建議要安裝的軟體包的名稱),您可以在它之前插入類似的內容:functions[command_not_found_handler]=' { if (( ! IN_CNFH++)) && load_lib "$1"; then "$@" return fi } always { (( IN_CNFH-- )) } '$functions[command_not_found_handler]
重擊
bash 中的等效項如下所示:
command_not_found_handle() { local ret if (( ! IN_CNFH++)) && load_lib "$1"; then "$@" ret=$? else printf >&2 '%s\n' "$BASH_ARGV0: $1: command not found: $1" ret=127 fi (( IN_CNFH-- )) return "$ret" }
或者增量變體,以防已經存在
command_not_found_handle
:eval 'command_not_found_handle() { local ret if (( ! IN_CNFH++)) && load_lib "$1"; then "$@" ret=$? (( IN_CNFH-- )) return "$ret" fi (( IN_CNFH-- )) '"$(typeset -f command_not_found_handle | tail -n +2)"' }'