Linux shell 如何避免重复加载环境变量?

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-static

export 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-static

export RUSTUP_UPDATE_ROOT=https://mirrors.ustc.edu.cn/rust-static/rustup

. "$HOME/.myenv/env"

. "$HOME/.cargo/env"

以上是 Linux shell 如何避免重复加载环境变量? 的全部内容, 来源链接: utcz.com/p/938299.html

回到顶部