为什么Ubuntu的默认〜/ .profile源〜/ .bashrc?

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

 if [ -n "$BASH_VERSION" ]; then if [ -f "$HOME/.bashrc" ]; then . "$HOME/.bashrc" fi fi if [ -d "$HOME/bin" ] ; then PATH="$HOME/bin:$PATH" fi 

这是inheritance自Debian但为什么Canonical决定保留它? 据我所知,它不是标准的* nix方式,我已经看到了各种系统没有发生这种情况,所以我认为它们必须有充分的理由。 这可能会导致运行登录shell时出现意外行为(例如,当sshing进入计算机时)用户不希望有~/.bashrc来源。

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

那么为什么Ubuntu这样做,我错过了什么?

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

我们以xdm为例。 皮尔有一天从假期回来,发现他的系统管理员已经在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浏览器inheritance了fluxbox的LANG变量,现在将其设置为错误的语言环境。 因此虽然他的xterms可能没问题,并且从他的xterms启动的任何东西都可能没问题,但他的网页浏览器仍然在错误的语言环境中给他提供页面。

那么,这个问题的最佳解决方案是什么? 真的没有普遍的。 更好的方法是将.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在/ etc / profile和.bash_profile中读取(如果它们存在且可读),然后再运行xmodmap或xterm或“执行”窗口管理器。 但是,这种方法存在一个潜在的缺点:在xdm下,读取.xsession的shell在没有控制终端的情况下运行。 如果/ etc / profile或.bash_profile使用任何假定存在终端的命令(例如“fortune”或“stty”),那么这些命令可能会失败。 这是xdm默认不读取这些文件的主要原因。 如果您打算使用这种方法,则必须确保在没有终端时“点文件”中的所有命令都可以安全运行。

这是Ubuntu的标准行为, ~/.bashrc是用户级per-interactive-shell启动文件。 当你打开一个终端时,基本上你会启动一个非登录的交互式shell ,它读取~/.bashrc并且~/.bashrc内容被获取并导出到你当前的shell环境中。 它有助于在当前shell中获取所有用户定义的shell变量函数 。 你也可以找到这样的行

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

在当前shell环境中获取用户定义的别名

这对于提供良好的用户体验也很重要。 例如,可以在.bashrc存储代理凭证,除非它获得来源终端应用程序( pingwgetcurllynx等)都不会正常工作。 或者,每次打开终端时都必须提供代理凭据。

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

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

要避免的情况

  • ~/.bashrc来自~/.profile时,你不应该在~/.bashrc中同时使用~/.profile 。 它将创建一个无限循环的情况,因此除非您按Ctrl + C,否则您的终端提示将被暂停。 在这种情况下,如果你在~/.bashrc一行
 设置-x 

然后您可以看到打开终端时文件描述符正在停止。