$PATH和source的作用
$PATH 是 Linux/Unix 系统中的一个环境变量,存储了一组用冒号 : 分隔的目录路径。
当你在终端输入一个命令(例如 dart 或 ls)时,Shell 会按照 $PATH 中列出的目录顺序依次搜索该命令的可执行文件。
例如,如果 $PATH=/usr/bin:/usr/local/bin,Shell 会先在 /usr/bin 中查找命令,如果没找到再去 /usr/local/bin 查找。
source ~/.zshrc 做了什么?
- 等价于把
.zshrc文件里的命令逐行执行一遍,让它们立刻生效在当前 shell 中。
PATH 是累积式的变量。你在 .zshrc 中做的是 export PATH=...:$PATH,如果旧路径已经存在于当前 $PATH 中,你执行 source ~/.zshrc 并不会清除掉原有的旧路径,除非你显式地从 $PATH 中删除它。
使用
echo $PATH命令可以查看完整路径变量。你会发现里面配置了许多路径,这些路径都是长年累月积累执行source ~/.zshrc命令积累下来的。(base) xieshaolin@xieshaolindeMacBook-Pro fvm % echo $PATH /usr/local/lib/ruby/gems/3.4.0/bin:/usr/local/opt/ruby/bin:/Users/xieshaolin/dev/tools/apache-maven-3.9.6/bin:/usr/local/mysql/bin:/Users/xieshaolin/.nvm/versions/node/v18.20.8/bin:/Users/xieshaolin/.pub-cache/bin:/Users/xieshaolin/fvm/default/bin/cache/dart-sdk/bin:/Users/xieshaolin/fvm/default/bin:/usr/local/lib/ruby/gems/3.4.0/bin:/usr/local/opt/ruby/bin:/Users/xieshaolin/dev/tools/apache-maven-3.9.6/bin:/usr/local/mysql/bin:/Users/xieshaolin/.nvm/versions/node/v18.20.8/bin:/usr/local/lib/ruby/gems/3.4.0/bin:/usr/local/opt/ruby/bin:/Users/xieshaolin/dev/tools/apache-maven-3.9.6/bin:/usr/local/mysql/bin:/Users/xieshaolin/.nvm/versions/node/v18.20.8/bin:/usr/local/lib/ruby/gems/3.4.0/bin:/usr/local/opt/ruby/bin:/Users/xieshaolin/dev/tools/apache-maven-3.9.6/bin:/usr/local/mysql/bin:/Users/xieshaolin/.nvm/versions/node/v18.20.8/bin:/usr/local/lib/ruby/gems/3.4.0/bin:/usr/local/opt/ruby/bin:/opt/miniconda3/bin:/opt/miniconda3/condabin:/Users/xieshaolin/dev/tools/apache-maven-3.9.6/bin:/usr/local/mysql/bin:/Users/xieshaolin/.nvm/versions/node/v18.20.8/bin:/Library/Frameworks/Python.framework/Versions/3.12/bin:/Library/Frameworks/Python.framework/Versions/3.13/bin:/usr/local/bin:/usr/local/sbin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/Library/Apple/usr/bin:/Users/xieshaolin/.nvm/versions/node/v14.21.3/bin:/Users/xieshaolin/dev/SDK/flutter/bin:/Users/xieshaolin/dev/SDK//bin/cache/dart-sdk/bin:/Users/xieshaolin/.pub-cache/bin:/Users/xieshaolin/Library/Android/sdk/platform-tools:/Users/xieshaolin/Library/Android/sdk/tools:/Users/xieshaolin/.nvm/versions/node/v14.21.3/bin:/Users/xieshaolin/fvm/default/bin:/Users/xieshaolin/fvm/default/bin/cache/dart-sdk/bin:/Users/xieshaolin/.pub-cache/bin:/Users/xieshaolin/Library/Android/sdk/platform-tools:/Users/xieshaolin/Library/Android/sdk/tools:/Users/xieshaolin/.nvm/versions/node/v14.21.3/bin:/Users/xieshaolin/fvm/default/bin:/Users/xieshaolin/fvm/default/bin/cache/dart-sdk/bin:/Users/xieshaolin/.pub-cache/bin:/Users/xieshaolin/Library/Android/sdk/platform-tools:/Users/xieshaolin/Library/Android/sdk/tools:/Users/xieshaolin/.nvm/versions/node/v14.21.3/bin:/Users/xieshaolin/Library/Android/sdk/platform-tools:/Users/xieshaolin/Library/Android/sdk/tools:/Users/xieshaolin/.nvm/versions/node/v14.21.3/bin:/Users/xieshaolin/fvm/default/bin:/Users/xieshaolin/fvm/default/bin/cache/dart-sdk/bin:/Users/xieshaolin/.pub-cache/bin:/Users/xieshaolin/Library/Android/sdk/platform-tools:/Users/xieshaolin/Library/Android/sdk/tools
为什么source ~/.zshrc不起作用
问题引入
我之前配置了一天这个路径
export PATH=${PATH}:~/dev/SDK/flutter/bin
后面是使用了fvm,需要修改flutter的SDK的路径,于是改成
export PATH=${PATH}:~/fvm/default/bin
并且把之前的配置都注释了。
改为之后,我source ~/.zshrc,但是发现配置没起作用:
(base) xieshaolin@xieshaolindeMacBook-Pro fvm % which flutter
/Users/xieshaolin/dev/SDK/flutter/bin/flutter
原因分析
PATH 是累积式的变量。我注释了原来的配置,但是并没有删除$PATH里面的环境变量
(base) xieshaolin@xieshaolindeMacBook-Pro fvm % echo $PATH | tr ':' '\n' | grep flutter
/Users/xieshaolin/dev/SDK/flutter/bin
/Users/xieshaolin/dev/SDK/flutter/bin/cache/dart-sdk/bin
原来旧路径的环境变量还是存在。
source ~/.zshrc等价于把 .zshrc 文件里的命令逐行执行一遍,让它们立刻生效在当前 shell 中。也就是从新把export PATH=${PATH}:~/fvm/default/bin这个命令执行一遍,但是没有删除~/dev/SDK/flutter/bin这个路径。
而export PATH=${PATH}:~/fvm/default/bin的意思是,将~/fvm/default/bin这个路径追加到现有的 $PATH 末尾。因此旧的路径在前面。当执行which flutter的时候,就会先找到就的路径~/dev/SDK/flutter/bin因此没有效果。
解决方法
前置到PATH开头
方法一:使用export PATH=~/fvm/default/bin:$PATH这种配置方式,改方式是将 ~/fvm/default/bin 前置到现有的 $PATH 开头。这意味着在命令查找时,会优先搜索~/fvm/default/bin 目录中的命令
手动删除PATH路径
export PATH=$(echo "$PATH" | tr ':' '\n' | grep -v '/dev/SDK/flutter/bin' | paste -sd ':')