在 Linux 中,据我所知,在所有 Unix 系统中,终端模拟器默认运行交互式、非登录 shell。这意味着,对于 bash,启动的 shell 将:
当启动非登录 shell 的交互式 shell 时,bash 会从
/etc/bash.bashrc和读取并执行命令~/.bashrc(如果这些文件存在)。这可以通过使用--norc选项来禁止 。该
--rcfile文件选项将强制bash读取和文件,而不是执行命令/etc/bash.bashrc和~/.bashrc。
对于登录 shell:
当 bash 作为交互式登录 shell 或作为具有
--login选项的非交互式 shell 调用时,它首先从文件中读取并执行命令/etc/profile(如果该文件存在)。读取该文件后,它会按该顺序查找~/.bash_profile、~/.bash_login、 和~/.profile,并从第一个存在且可读的命令中读取和执行命令。
--noprofile当 shell 启动时可以使用该选项来禁止这种行为。
在OSX上,但是,默认壳(这是bash)的开始在缺省终端(Terminal.app)实际上源~/.bash_profile或~.profile等等。换句话说,它的作用就像一个登录shell。
主要问题:为什么默认的交互式 shell 是 OSX 上的登录 shell?为什么 OSX 选择这样做?这意味着所有提及更改内容的基于 shell 的内容的说明/教程~/.bashrc在 OSX 上都将失败,反之亦然~/.profile。尽管如此,尽管可以对 Apple 提出许多指控,但雇用无能或愚蠢的开发人员并不是其中之一。据推测,他们有充分的理由这样做,那为什么呢?
子问题:Terminal.app 是否真的运行了一个交互式登录 shell 或者他们是否改变了 bash 的行为?这是特定于 Terminal.app 还是独立于终端模拟器?
Ilm*_*nen 43
它就是这样认为的工作是,在点当你得到一个shell提示符下,双方.profile并.bashrc已运行。您如何达到这一点的具体细节是次要的,但是如果根本没有运行任何一个文件,那么您将拥有一个设置不完整的外壳。
Linux(和其他基于 X 的系统)上的终端模拟器不需要自己运行的原因.profile是它通常在您登录到 X 时已经运行了。 中的设置.profile应该是那种可以由子进程继承,因此只要在您登录时执行一次(例如 via .Xsession),任何进一步的子shell 都不需要重新运行它。
正如Alan Shutko 链接的Debian wiki 页面所解释的那样:
“那么为什么是
.bashrc一个单独的文件.bash_profile?这样做主要是出于历史原因,当时机器与今天的工作站相比非常慢。处理命令.profile或.bash_profile可能需要相当长的时间,尤其是在有大量工作的机器上必须由外部命令(预 bash)完成。因此,将创建可以传递给子进程的环境变量的困难的初始设置命令放入.bash_profile. 未继承的瞬态设置和别名在.bashrc这样他们可以通过每个子shell重读“。
所有相同的规则也适用于 OSX,除了一件事——OSX GUI.profile在您登录时不会运行,这显然是因为它有自己的加载全局设置的方法。但这意味着 OSX上的终端模拟器确实需要运行.profile(通过告诉 shell 它启动它是一个登录 shell),否则你最终会得到一个可能瘫痪的 shell。
现在,bash 有一个愚蠢的特性,大多数其他 shell 都不共享,.bashrc如果它作为登录 shell 启动,它将不会自动运行。标准的解决方法是在 中包含类似以下命令的内容.bash_profile:
[[ -e ~/.profile ]] && source ~/.profile # load generic profile settings
[[ -e ~/.bashrc ]] && source ~/.bashrc # load aliases etc.
Run Code Online (Sandbox Code Playgroud)
或者,也可以完全没有.bash_profile,只需在通用.profile文件中包含一些特定于 bash 的代码即可在.bashrc需要时运行。
如果 OSX 默认.bash_profile或.profile 不这样做,那么这可以说是一个错误。在任何情况下,正确的解决方法是简单地将这些行添加到.bash_profile.
编辑: 正如 strugee 指出的那样,OSX 上的默认 shell 曾经是 tcsh,在这方面它的行为更加理智:当作为交互式登录 shell 运行时,tcsh 会自动读取.profile 和 .tcshrc/ .cshrc,因此不需要任何变通方法,例如.bash_profile技巧如上所示。
基于此,我 99% 肯定 OSX 未能提供适当的默认值.bash_profile是因为当他们从 tcsh 切换到 bash 时,Apple 的人们根本没有注意到 bash 启动行为中的这个小问题。使用 tcsh,不需要这样的技巧——从 OSX 终端仿真器 Just Plain Works 将 tcsh 作为登录 shell 启动,并在没有这些kluges 的情况下做正确的事情。
Ala*_*tko 15
X 终端应用程序默认运行非登录 shell 的主要原因是,在开始时,您的 .Xsession 会运行 .profile 来设置您的初始登录项。然后,因为这一切都已经设置好了,终端应用程序不需要运行它,他们可以运行 .bashrc。关于为什么这很重要的讨论在https://wiki.debian.org/DotFiles:
我们以 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 浏览器继承了 Fluxbox 的 LANG 变量,该变量现在设置为错误的语言环境。因此,尽管他的 xterms 可能没问题,并且从他的 xterms 启动的任何内容都可能没问题,但他的 Web 浏览器仍然为他提供了错误区域设置的页面。
在 OS X 上,用户环境不是由一堆 shell 脚本启动的,并且 launchd 不会在任何时候提供 .profile。(这有点可惜,因为这意味着设置环境变量要烦人得多,但这就是生活。)既然没有,那么它什么时候运行 .profile? 仅当您通过 ssh 登录时?这似乎毫无意义,因为许多盒子永远不会成为 ssh 的目标。不妨让终端默认运行登录 shell,以便 .profile 将在某个时候运行。
那么 .bashrc 呢?没用吗?不。它仍然具有它在 VT100 时代的用途。它用于打开终端窗口以外的任何时间打开外壳。因此,如果您使用 Emacs 或 vi,或者您使用 su 用户。
我不知道他们为什么会这样做。但是,这是我的猜测。
首先,值得注意的是,在 GNU/Linux 系统上,您当然可以切换到 vt1、vt2 等。您会在那里获得登录 shell。在 OS X 系统上,没有等价物。访问 UNIX 基础的唯一方法是通过终端仿真器或通过单用户模式(免责声明:我从未真正使用过单用户模式;它是命令行驱动的 IIRC,但我可能错了)。因此,在 OS X 中,模拟器中的任何默认设置都是整个系统的默认设置。
现在,为什么要使默认登录 shell ?我能想到这样做的几个原因(阅读:不是很多)。
tcsh. 这是您所能得到的最疯狂的猜测,但可能是tcsh在作为登录 shell 运行时通常会做一些事情,并且历史模式卡住了。(不过,我对此表示怀疑 - 也许一位年长的常客可以告诉我们。)老实说,我已经使用 Darwin 大约 6 年了,我无法正确回答这个问题。这对我来说也没有意义。
要回答您的子问题,bash没有打补丁或任何东西(至少为此)。默认终端模拟器默认运行登录 shell,大概 iTerm 会复制它。
| 归档时间: |
|
| 查看次数: |
17285 次 |
| 最近记录: |