pyenv 2.0.0+初始化配置全放.bash_profile的弊端咨询
官方拆分配置到两个文件的核心原因
bash的不同启动模式加载的配置文件不一样:
- 登录式shell(比如macOS默认打开终端、SSH远程登录的场景)会加载
~/.bash_profile,这类场景通常是你第一次进入shell环境,只需要初始化一次全局环境变量就行。 - 交互式非登录shell(比如在现有终端中执行
bash开启子shell、部分编辑器内置终端的默认启动模式)只会加载~/.bashrc,不会读取~/.bash_profile。
官方的拆分逻辑刚好匹配这个启动规则:
eval "$(pyenv init --path)"作用是把pyenv的shims目录写入系统PATH,只需要执行一次就会全局生效,重复执行也不会有额外收益,所以放在只加载一次的~/.bash_profile里。eval "$(pyenv init -)"作用是加载pyenv的命令补全、版本自动切换钩子等shell级功能,这些功能需要每个交互式shell启动时都加载一次,所以放在每个交互式shell都会读取的~/.bashrc里。
两行全写入
~/.bash_profile的弊端 - 非登录式的交互式shell会丢失pyenv的扩展功能:比如你手动开子shell、用部分编辑器内置终端时,会发现pyenv命令补全失效、当前目录的Python版本不会自动切换,严重时甚至会找不到pyenv管理的Python版本。
- 跨系统使用时会直接失效:Linux发行版的图形界面终端默认大多以非登录模式启动,根本不会读取
~/.bash_profile,会导致pyenv完全没有被初始化。 - 特殊场景下会拖慢shell启动速度:如果你的
~/.bash_profile被重复触发执行,pyenv init -会重复注册钩子函数,虽然不会直接报错,但会增加shell的启动耗时。
未来使用是否会触发问题
如果你始终仅在当前macOS环境使用,且所有用到bash的场景都是登录式shell,目前的写法基本不会触发明显问题。
但如果后续有跨系统使用需求、或者用到非登录交互式shell的场景,大概率会出现功能异常。
如果必须把所有配置都放在~/.bash_profile里,可以调整为如下写法,尽可能降低潜在问题:
# ~/.bash_profile eval "$(pyenv init --path)" # 仅在交互式shell场景加载pyenv的shell级功能 if [[ $- == *i* ]]; then eval "$(pyenv init -)" fi
内容的提问来源于stack exchange,提问作者jameslouie
相关产品推荐
相关产品推荐

