Debian12在.bashrc中添加环境变量后每次启动终端都必须"source ~/.bashrc"

如果你的 .bashrc 是 Debian 默认模板,那它应该有这么一段:

case $- in
    *i*) ;;
      *) return;;
esac

这段内容的含义是,如果该 bash 处于 交互模式 则提前结束,不执行后面的代码。

如果你打算让脚本也能用相关的环境变量(即 PATH),那么你需要在这段代码前处理 PATH。或者你打算只是在交互模式下使用修改后的 PATH 方便自己,那么就在这段代码后修改 PATH


需要注意的是修改环境变量的一个潜在风险是你可能会污染桌面环境下的所有进程。

如果你打算让修改对所有桌面进程和 ssh 登陆用户生效,那么你可能会需要修改 .profile 文件。
而具体那些部分代码和配置会在哪些情况下被执行,又可能取决于

  • shell 是 dash/sh 还是 bash
  • 是否是登录 shell
  • 是否是交互模式。
  • 当前桌面环境屏幕管理器如何处理用户配置

如果想让修改在 X11 相关环境中也生效,那么可能需要修改 ~/.xsession 这个文件。Wayland 可能有另外的配置路径。

另外 .profile 默认的模板有如下代码:

if [ "$BASH" ]; then
    if [ -f ~/.bashrc ]; then
        . ~/.bashrc
    fi
fi

因此只有在运行 .profile 的 shell 是 bash 的情况下才会从 .profile 运行 .bashrc

但是实际情况比这个更复杂:
如果 shell 是 bash,非登陆的交互 bash 会直接运行 .bashrc,而登陆的交互 bash 会从 .bash_profile 回退到 .profile(如果 .bash_profile 不存在)。


总的来说,shell 配置加载顺序是非常复杂的,建议详细阅读相关的文章。

推荐的最佳实践是:

  • 不依赖 shell 的非交互状态的环境变量修改放在 .profile
  • bash 特定的环境变量修改放在 .bashrc
  • 取决于交互还是非交互,需要检查是否为交互终端分情况修改
  • 考虑到有可能多次对 PATH 进行修改,应当检查是否已经进行过修改

对于第四点,个人使用的代码是:

# 如果 $HOME/.local/bin 目录存在
if [ -d "$HOME/.local/bin" ] ; then
  case ":${PATH}:" in
    *:"$HOME/.local/bin":*)
      ;;
    *)
      # 只有当 $PATH 中不包含 $HOME/.local/bin 时才添加
      PATH="$HOME/.local/bin:$PATH"
      ;;
  esac
fi

学到了,感谢您的指点。刚刚接触,确实还有很多需要学习。