原因在于,pyenv-virtualenv 修改了 PROMPT_COMMAND 这个环境变量:
PROMPT_COMMAND=_pyenv_virtualenv_hook;history -a; { z=$(history 1 | { read x y; echo $y; }); echo -n [ $(date "+%c") ]; echo -n [ $(who am i) ] ; echo [ $z ]; } >> /data/.my_history
而 _pyenv_virtualenv_hook 这个函数,是在 ~/.pyenv/plugins/pyenv-virtualenv/bin/pyenv-virtualenv-init 文件中定义的,通过 su 命令切换到 root 用户时,这个环境变量带过去了,但是 _pyenv_virtualenv_hook 定义却不在 root 用户目录下面中,所以找不到这个函数定义。
PROMPT_COMMAND 是 bash 的环境变量,这个变量的中内容是作为一个普通的 bash 命令执行的,而且执行时间是在 bash 显示 prompt 之前。 这个好理解,就是说每执行一个命令前,PROMPT_COMMAND 里面先执行,然后是 prompt。
所以,在 su 进入 root 后,每个命令执行完,都会报错:
bash: _pyenv_virtualenv_hook: 未找到命令
解决办法,编辑 ~/.pyenv/plugins/pyenv-virtualenv/bin/pyenv-virtualenv-init 文件:
142 #if ! [[ "\$PROMPT_COMMAND" =~ _pyenv_virtualenv_hook ]]; then 143 # PROMPT_COMMAND="_pyenv_virtualenv_hook;\$PROMPT_COMMAND"; 144 #fi 145 EOS 146 ;; 147 zsh ) 148 cat << EOS 149 typeset -g -a precmd_functions 150 #if [[ -z \$precmd_functions[(r)_pyenv_virtualenv_hook] ]]; then 151 # precmd_functions=(_pyenv_virtualenv_hook \$precmd_functions); 152 #fi 153 EOS
加上以上注释,如图: