Linux shell 如何避免重复加载环境变量?
使用 zsh
,每次 source
或者打开子 shell
的时候都会重复加载环境变量
原本的环境变量:?
─➤ echo -e ${PATH//:/\\n}/home/bot/.cargo/bin
/home/bot/opt/go/bin
/home/bot/.local/bin
/home/bot/opt/pycharm/pycharm-2021.2/bin
/home/bot/opt/python3.10.1/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin
子 shell
中的环境变量?
─➤ echo -e ${PATH//:/\\n}/home/bot/.local/share/virtualenvs/ideaboom-3stdf9Mx/bin
/home/bot/opt/go/bin
/home/bot/.local/bin
/home/bot/opt/pycharm/pycharm-2021.2/bin
/home/bot/opt/python3.10.1/bin
/home/bot/.cargo/bin
/home/bot/opt/go/bin
/home/bot/.local/bin
/home/bot/opt/pycharm/pycharm-2021.2/bin
/home/bot/opt/python3.10.1/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin
可以看到开头这部分变量被重新加载了?
/home/bot/opt/go/bin/home/bot/.local/bin
/home/bot/opt/pycharm/pycharm-2021.2/bin
/home/bot/opt/python3.10.1/bin
造成重复加载环境变量的原因,我猜测是每个子 shell
都会重新跑一遍 ~/.zshenv
文件!
我的 ~/.zshenv
文件?
export RUSTUP_DIST_SERVER=https://mirrors.ustc.edu.cn/rust-staticexport RUSTUP_UPDATE_ROOT=https://mirrors.ustc.edu.cn/rust-static/rustup
export PATH=/home/bot/opt/python3.10.1/bin:$PATH
export PATH=/home/bot/opt/pycharm/pycharm-2021.2/bin:$PATH
export PATH=/home/bot/.local/bin:$PATH
export PATH=/home/bot/opt/go/bin:$PATH
. "$HOME/.cargo/env"
其中的 "$HOME/.cargo/env"
脚本有去重的功能,参考了 "$HOME/.cargo/env"
防止重复加载环境变量的做法:
#!/bin/sh# rustup shell setup
# affix colons on either side of $PATH to simplify matching
case ":${PATH}:" in
*:"$HOME/.cargo/bin":*)
;;
*)
# Prepending path in case a system-installed rustc needs to be overridden
export PATH="$HOME/.cargo/bin:$PATH"
;;
esac
但是这个脚本的 shell
语法让我看不懂,有什么简单的办法可以封装一下就能防止在子 shell
中重复加载环境变量吗?
越简单优雅越好!???
回答:
楼上的方法也是不恰当的,因为它要么存在一个就全部不再加,要么一次性全部加上,其实正确的脚本应该是
#!/bin/sh# rustup shell setup
# 下面分别对每个路径进行测试,判断是否需要增加到PATH环境变量中去。
case ":${PATH}:" in
*:"${HOME}/opt/go/bin":*)
;;
*)
export PATH=${HOME}/opt/go/bin:${PATH}
;;
esac
case ":${PATH}:" in
*:"${HOME}/.local/bin":*)
;;
*)
export PATH=${HOME}/.local/bin:${PATH}
;;
esac
case ":${PATH}:" in
*:"${HOME}/opt/pycharm/pycharm-2021.2/bin":*)
;;
*)
export PATH=${HOME}/opt/pycharm/pycharm-2021.2/bin:${PATH}
;;
esac
case ":${PATH}:" in
*:"${HOME}/opt/python3.10.1/bin":*)
;;
*)
export PATH=${HOME}/opt/python3.10.1/bin:${PATH}
;;
esac
另外一种写法可能更简洁,总之一个原则是判断PATH中是否包含待加入的路径:
#!/bin/sh# 下面分别对每个路径进行测试,判断是否需要增加到PATH环境变量中去。
if [[ ":${PATH}:" != *":${HOME}/opt/go/bin:"* ]]; then
export PATH=${HOME}/opt/go/bin:${PATH}
fi
if [[ ":${PATH}:" != *":${HOME}/.local/bin:"* ]]; then
export PATH=${HOME}/.local/bin:${PATH}
fi
if [[ ":${PATH}:" != *":${HOME}/opt/pycharm/pycharm-2021.2/bin:"* ]]; then
export PATH=${HOME}/opt/pycharm/pycharm-2021.2/bin:${PATH}
fi
if [[ ":${PATH}:" != *":${HOME}/opt/python3.10.1/bin:"* ]]; then
export PATH=${HOME}/opt/python3.10.1/bin:${PATH}
fi
这里的关键是用*
通配符展开字符串进行比较,判断包含关系,而加的:
是因为PATH
环境变量是以它分隔各个搜索路径,这样添加了可以保证完整匹配路径。
回答:
#!/bin/sh# rustup shell setup
# affix colons on either side of $PATH to simplify matching
case ":${PATH}:" in
*:"$HOME/opt/go/bin":*)
;;
":${PATH}:" in
*:"$HOME/.local/bin":*)
;;
":${PATH}:" in
*:"$HOME/opt/pycharm/pycharm-2021.2/bin":*)
;;
":${PATH}:" in
*:"$HOME/opt/python3.10.1/bin":*)
;;
*)
# Prepending path in case a system-installed rustc needs to be overridden
export PATH=/home/bot/opt/python3.10.1/bin:$PATH
export PATH=/home/bot/opt/pycharm/pycharm-2021.2/bin:$PATH
export PATH=/home/bot/.local/bin:$PATH
export PATH=/home/bot/opt/go/bin:$PATH
;;
esac
在"$HOME/.myenv/"路径下保存上面的脚本为env,添加可执行权限,修改~/.zshenv 文件:
export RUSTUP_DIST_SERVER=https://mirrors.ustc.edu.cn/rust-staticexport RUSTUP_UPDATE_ROOT=https://mirrors.ustc.edu.cn/rust-static/rustup
. "$HOME/.myenv/env"
. "$HOME/.cargo/env"
以上是 Linux shell 如何避免重复加载环境变量? 的全部内容, 来源链接: utcz.com/p/938299.html