为什么 Ubuntu 默认的 ~/.profile 会来源 ~/.bashrc?

为什么 Ubuntu 默认的 ~/.profile 会来源 ~/.bashrc?

~/.profile这些是我的 13.10 附带的库存内容(删除了注释行):

if [ -n "$BASH_VERSION" ]; then
    if [ -f "$HOME/.bashrc" ]; then
    . "$HOME/.bashrc"
    fi
fi

if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi

这是从 Debian 继承而来的,但为什么 Canonical 决定保留它?据我所知,这不是标准的 *nix 方式,而且我见过各种系统都没有发生这种情况,所以我猜想他们一定有充分的理由这样做。在运行登录 shell(例如,当 ssh 进入机器时)时,这可能会导致意外行为,而用户不会期望这样做~/.bashrc

我能想到的唯一好处是不会让用户对许多启动文件感到困惑,并允许他们.bashrc单独编辑并读取这些文件,而不管 shell 类型如何。然而,这是一个可疑的好处,因为通常对登录和交互式 shell 有不同的设置很有用,而这会阻止您这样做。此外,登录 shell 通常不在图形环境中运行,这可能会导致错误、警告和问题(天哪!),具体取决于您在这些文件中设置的内容。

那么 Ubuntu 为什么会这样做?我忽略了什么?

答案1

这是 Debian 的上游决定。这个非常好的文档解释了其基本原理。维基帖子,其中以下内容摘录如下。执行摘要是“确保 GUI 和非 GUI 登录以相同的方式工作”:

让我们以 xdm 为例。pierre 有一天度假回来,发现他的系统管理员在 Debian 系统上安装了 xdm。他登录正常,xdm 读取了他的 .xsession 文件并运行 fluxbox。一切似乎都正常,直到他收到错误语言环境中的错误消息!由于他覆盖了 .bash_profile 中的 LANG 变量,并且 xdm 从不读取 .bash_profile,因此他的 LANG 变量现在设置为 en_US 而不是 fr_CA。

现在,这个问题的简单解决方案是,他可以将窗口管理器配置为启动“xterm -ls”,而不是启动“xterm”。此标志告诉 xterm,它应该启动登录 shell,而不是启动普通 shell。在这种设置下,xterm 会生成 /bin/bash,但它会在参数向量中放入“-/bin/bash”(或可能是“-bash”),因此 bash 就像一个登录 shell。这意味着每次他打开一个新的 xterm 时,它都会读取 /etc/profile 和 .bash_profile(内置 bash 行为),然后读取 .bashrc(因为 .bash_profile 要求这样做)。乍一看,这似乎运行良好——他的点文件并不重,所以他甚至没有注意到延迟——但还有一个更微妙的问题。他还直接从 fluxbox 菜单启动了一个 web 浏览器,web 浏览器从 fluxbox 继承了 LANG 变量,而该变量现在设置为错误的语言环境。因此,尽管他的 xterms 可能没有问题,并且从他的 xterms 启动的任何内容可能都没有问题,但他的 Web 浏览器仍然会向他提供错误语言环境的页面。

那么,这个问题的最佳解决方案是什么?实际上并没有一个通用的解决方案。更好的方法是修改 .xsession 文件,使其看起来像这样:

[ -r /etc/profile ] && source /etc/profile
[ -r ~/.bash_profile ] && source ~/.bash_profile
xmodmap -e 'keysym Super_R = Multi_key'
xterm &
exec fluxbox

这会导致解释 .xsession 脚本的 shell 在运行 xmodmap 或 xterm 或“执行”窗口管理器之前读取 /etc/profile 和 .bash_profile(如果它们存在且可读)。但是,这种方法有一个潜在的缺点:在 xdm 下,读取 .xsession 的 shell 在没有控制终端的情况下运行。如果 /etc/profile 或 .bash_profile 使用任何假定存在终端的命令(例如“fortune”或“stty”),这些命令可能会失败。这是 xdm 默认不读取这些文件的主要原因。如果您要使用此方法,您必须确保“点文件”中的所有命令在没有终端时都可以安全运行。

答案2

这是 Ubuntu 的标准行为,~/.bashrc是用户级的交互式 shell 启动文件。当你打开终端时,基本上就是启动一个无需登录,交互式 shell 它读取并导出~/.bashrc的内容到您当前的 shell 环境中。它有助于获取所有用户定义的~/.bashrcshell 变量功能在当前 shell 中。您还可以找到类似这样的行

if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

获得用户定义别名在当前 shell 环境中。

这对于提供良好的用户体验也很重要。例如,可以将代理凭据存储在 中.bashrc,除非它来自任何终端应用程序(、、、、等)将正常工作。或者每次打开终端时ping都必须提供代理凭据。wgetcurllynx

除了 Ubuntu 默认.bashrc包含许多用户友好的别名(用于lsgrep打印彩色输出)之外,许多不同的 shell 变量的新定义也增加了用户体验。

但如果你ssh 登录, 或者登录虚拟控制台,你基本上会得到一个交互式登录 shell。shell 启动文件是~/.profile。因此,除非你使用 source 命令,否则~/.bashrc你会错过所有有用的设置.bashrc。这就是为什么 Ubuntu 的默认~/.profilesource 命令~/.bashrc

应避免的情况

  • 你永远不应该同时~/.profile从 内部获取源。这将导致无限循环,结果你的终端提示将被暂停,除非你按下+ 。在这种情况下,如果你在你的~/.bashrc~/.bashrc~/.profileCtrlC~/.bashrc
设置-x

然后,当您打开终端时,您就会看到文件描述符正在停止。

相关内容