zsh中command_not_found_handler函数更新全局变量失败求助
解决zsh command_not_found_handler全局变量不更新问题
问题背景
需要修改zsh的command_not_found_handler函数,实现两个功能:
- 输入未安装的命令时,打印对应的包安装指令
- 将该安装指令存储到全局变量
SUGGESTION_CMD中
当前使用的代码如下:
# this function provides command to install that packge if its not installed command_not_found_handler() { cmd="$1" prt="zsh: command not found: $cmd" package=$(pacman -Ss "^$cmd$" | grep "/$cmd " | awk -F '/' '{print $2}' | cut -d' ' -f1) SUGGESTION_CMD="NOT FOUND" if [[ -n "$package" ]]; then SUGGESTION_CMD="pacman -S $package" prt="$prt ($SUGGESTION_CMD)\a" fi echo $prt return 127 } export SUGGESTION_CMD
但执行后全局变量未更新,测试情况:
$ gimp zsh: command not found: gimp (pacman -S gimp) $ echo $SUGGESTION_CMD $ command_not_found_handler zsh: command not found: $ echo $SUGGESTION_CMD NOT FOUND
问题原因
zsh自动调用command_not_found_handler处理未找到的命令时,会在子进程中执行该函数,函数内的变量默认是局部作用域,即使提前export变量,子进程内的修改也无法同步到父shell的全局环境。直接手动调用函数时变量能更新,是因为此时函数在当前shell进程内执行。
解决方案
使用zsh的typeset -g命令声明全局变量,确保函数内对变量的修改直接作用于父shell的全局环境,无需提前export。
修改后的代码:
# this function provides command to install that package if its not installed command_not_found_handler() { local cmd="$1" local prt="zsh: command not found: $cmd" local package=$(pacman -Ss "^$cmd$" | grep "/$cmd " | awk -F '/' '{print $2}' | cut -d' ' -f1) # 声明全局变量,确保修改同步到父shell typeset -g SUGGESTION_CMD="NOT FOUND" if [[ -n "$package" ]]; then SUGGESTION_CMD="pacman -S $package" prt="$prt ($SUGGESTION_CMD)\a" fi echo "$prt" return 127 }
验证测试
执行未安装的命令后,全局变量会正确更新:
$ gimp zsh: command not found: gimp (pacman -S gimp) $ echo $SUGGESTION_CMD pacman -S gimp $ nonexistentcmd zsh: command not found: nonexistentcmd (NOT FOUND) $ echo $SUGGESTION_CMD NOT FOUND
内容的提问来源于stack exchange,提问作者Mahmood Jamshidian
相关产品推荐
相关产品推荐

