问题描述
最近我将MacOS更新为Catalina。现在默认的shell是 zsh ,我想将其恢复为bash,但我想继续玩。现在,我想自定义命令提示符时遇到了一个问题。
我在 $HOME/.zshenv
中声明;
export ZDOTDIR="$XDG_CONfig_HOME/zsh"
在该文件夹中,我有 .zshrc
文件。它包含conda初始化的一部分。
# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$('/Users/finn/anaconda3/bin/conda' 'shell.zsh' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
eval "$__conda_setup"
else
if [ -f "/Users/finn/anaconda3/etc/profile.d/conda.sh" ]; then
. "/Users/finn/anaconda3/etc/profile.d/conda.sh"
else
export PATH="/Users/finn/anaconda3/bin:$PATH"
fi
fi
unset __conda_setup
# <<< conda initialize <<<
但更重要的是,我获得了这个 prompt.sh
文件:
function promptcmd () {
local blue="{33}";
local cyan="{87}";
local orange="{160}";
local pink="{200}";
local white="{15}";
local yellow="{226}";
# Set the terminal title and prompt.
PROMPT=""; # working directory base name
PROMPT+="%B"; # all bold
PROMPT+="%F${pink}%n%f"; # username
PROMPT+="%F${yellow}@%f"; # at
PROMPT+="%F${orange}%M%f"; # hostname
PROMPT+="%F${white} in %f"; # in
PROMPT+="%F${blue}%~%f"; # directory
PROMPT+="%F${white} \$ %f%b";
if [[ $CONDA_DEFAULT_ENV != "base" ]]; then
RPROMPT="%F${cyan}($CONDA_DEFAULT_ENV)%f";
fi;
}
promptcmd
PROMPT
部分工作正常。但是我想在右侧显示我的 Anaconda Environment 的部分却没有。问题是环境变量$CONDA_DEFAULT_ENV
的读取不正确。如果我只是在提示符下显示变量(不带if
语句),即使我键入了(base)
,然后输入了conda activate my_env
,我仍然看到变量始终保持echo $CONDA_DEFAULT_ENV
的状态。然后返回my_env
。
.zshrc
是否不重新读取环境变量?
编辑:
切德纳的表扬得到了帮助;只是通过重命名您仅拨打一次
promptcmd
;您想改为定义precmd
(或从promptcmd
内部定义所有promptcmd
),以便在每次显示提示之前重新定义提示。
promptcmd
函数,它首先以某种方式起作用。 RPROMPT
为空,直到我conda activate my_env
,然后说(my_env)
。但是随后出现了一些奇怪的行为,我只能告诉你:
解决方法
在zsh手册页中:
...然后从$ ZDOTDIR / .zshenv中读取命令。 ....然后,如果外壳是交互式的,则从/ etc / zshrc中读取命令,然后从$ ZDOTDIR / .zshrc中读取命令。
如果未设置ZDOTDIR,则使用您的$HOME
。我不知道conda激活是如何工作的,但是可以合理地假设它创建了一个新的zsh子进程。现在,此子进程已定义ZDOTDIR
,指向与您的HOME不同的目录,并且您的$HOME/.zshrc
将不会被获取。
在 EDIT 前,缺少两个部分。
感谢chepner的评论,我发现了其中的第一个:
您仅拨打一次
promptcmd
;您想要定义precmd
而不是[...],以便在每次显示提示之前重新定义提示。
显然有这种命名约定,当打开新的“终端”窗口时,导致我的函数promptcmd
仅执行一次。如果将其重命名为precmd
,则会在每个提示符下执行。
然后,我在问题的EDIT中显示了该问题。每次激活新的conda env时它都起作用,因为$ CONDA_DEFAULT_ENV与base
不同,后者导致if
子句执行并将RPROMPT
设置为"%F${cyan}($CONDA_DEFAULT_ENV)%f"
。现在,当我输入conda deactivate
并且$CONDA_DEFAULT_ENV
回到base
时,它就不会从提示的右侧消失。经过user1934428的评论,我学会了一种更容易调试的方法后:
如果您具有必要的权限,我会在
set -x
中的第一个命令中放置一个/etc/zshenv
,因为这是执行开始的地方。当然这会影响所有用户。如果您不想这样做,请将其放在~/.zshenv
的顶部。
然后,我很快意识到,$RPROMPT
根本没有在我天真的假定的自定义提示功能precmd
之前被重置。因此解决了最后一部分的是RPROMPT=""
之前的简单if
,它在$CONDA_DEFAULT_ENV
不是base
时设置了RPROMPT。