解决pyenv-virtualenv在su进入root后报错:_pyenv_virtualenv_hook command not found

原因在于,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

加上以上注释,如图: