.zshrc 文件中的环境变量读取不正确
Environment Variable is read incorrectly in .zshrc file
最近我将我的 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
没有重新读取环境变量吗?
编辑:
You are only calling promptcmd
once; you want to define precmd
instead (or all promptcmd
from inside promptcmd
) so that your prompt is redefined just before it is displayed every time.
chedner 的评论很有帮助;只需重命名 promptcmd
函数,它起初就可以正常工作。在 conda activate my_env
之前 RPROMPT
是空的,然后它显示 (my_env)
。但是随后出现了一些奇怪的行为,我只能告诉你:
来自 zsh 手册页:
... Commands are then read from $ZDOTDIR/.zshenv. .... Then, if the shell is interactive, commands are read from /etc/zshrc and then $ZDOTDIR/.zshrc.
如果未设置 ZDOTDIR,则使用您的 $HOME
。我不知道 conda 激活是如何工作的,但可以合理地假设它创建了一个新的 zsh 子进程。此子进程现在已定义 ZDOTDIR
,指向与您的 HOME 不同的目录,并且您的 $HOME/.zshrc
将不会被获取。
在 EDIT 之前 缺少两部分。
由于 chepner 的评论,我发现了其中的第一个,其中引用了:
You are only calling promptcmd
once; you want to define precmd
instead [...] so that your prompt is redefined just before it is displayed every time.
显然有这个命名约定,这导致我的函数 promptcmd
在打开新终端 window 时只执行一次。如果将其重命名为 precmd
,它会在 每个 提示时执行。
然后我在问题的编辑中显示了这个问题。每次激活新的 conda env 时它都会工作,因为 $CONDA_DEFAULT_ENV 不同于 base
导致执行 if
子句并将 RPROMPT
设置为 "%F${cyan}($CONDA_DEFAULT_ENV)%f"
.现在,当我输入 conda deactivate
并且 $CONDA_DEFAULT_ENV
返回到 base
时,它从未从提示符的右侧消失。由于 user1934428 的评论,我学会了一种更容易调试的方法:
If you have the necessary permissions, I would put a set -x
at the first command in /etc/zshenv
, because this is where execution starts. Of course this will affect all users. If you don't want to do this, put it at the top of your ~/.zshenv
.
然后,我很快意识到,$RPROMPT
根本没有在我的自定义提示函数 precmd
之前重置,这是我天真地假设的。那么解决最后一部分的是 if
之前的简单 RPROMPT=""
,它在 $CONDA_DEFAULT_ENV
不是 base
时设置 RPROMPT。
最近我将我的 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
没有重新读取环境变量吗?
编辑:
You are only calling
promptcmd
once; you want to defineprecmd
instead (or allpromptcmd
from insidepromptcmd
) so that your prompt is redefined just before it is displayed every time.
chedner 的评论很有帮助;只需重命名 promptcmd
函数,它起初就可以正常工作。在 conda activate my_env
之前 RPROMPT
是空的,然后它显示 (my_env)
。但是随后出现了一些奇怪的行为,我只能告诉你:
来自 zsh 手册页:
... Commands are then read from $ZDOTDIR/.zshenv. .... Then, if the shell is interactive, commands are read from /etc/zshrc and then $ZDOTDIR/.zshrc.
如果未设置 ZDOTDIR,则使用您的 $HOME
。我不知道 conda 激活是如何工作的,但可以合理地假设它创建了一个新的 zsh 子进程。此子进程现在已定义 ZDOTDIR
,指向与您的 HOME 不同的目录,并且您的 $HOME/.zshrc
将不会被获取。
在 EDIT 之前 缺少两部分。
由于 chepner 的评论,我发现了其中的第一个,其中引用了:
You are only calling
promptcmd
once; you want to defineprecmd
instead [...] so that your prompt is redefined just before it is displayed every time.
显然有这个命名约定,这导致我的函数 promptcmd
在打开新终端 window 时只执行一次。如果将其重命名为 precmd
,它会在 每个 提示时执行。
然后我在问题的编辑中显示了这个问题。每次激活新的 conda env 时它都会工作,因为 $CONDA_DEFAULT_ENV 不同于 base
导致执行 if
子句并将 RPROMPT
设置为 "%F${cyan}($CONDA_DEFAULT_ENV)%f"
.现在,当我输入 conda deactivate
并且 $CONDA_DEFAULT_ENV
返回到 base
时,它从未从提示符的右侧消失。由于 user1934428 的评论,我学会了一种更容易调试的方法:
If you have the necessary permissions, I would put a
set -x
at the first command in/etc/zshenv
, because this is where execution starts. Of course this will affect all users. If you don't want to do this, put it at the top of your~/.zshenv
.
然后,我很快意识到,$RPROMPT
根本没有在我的自定义提示函数 precmd
之前重置,这是我天真地假设的。那么解决最后一部分的是 if
之前的简单 RPROMPT=""
,它在 $CONDA_DEFAULT_ENV
不是 base
时设置 RPROMPT。