为什么是“登录”外壳而不是“非登录”外壳?

Xle*_*lee 47 shell login terminology unix-philosophy

我对*nix 系统中的dotfiles有一个基本的了解。但是我仍然对登录外壳和非登录外壳之间的区别感到很困惑

一堆不同的答案(包括多个重复)已经解决了以下要点:

  • 如何调用一个登录非登录
  • 如何检测一个登录或者非登录
  • 什么启动文件将被消耗登录或者非登录
  • man bash有关更多详细信息,请参阅文档(例如,)

答案没有告诉(以及我仍然感到困惑的事情)是:

  • 什么是用例一的登录或者非登录壳呢?(例如,我只配置zshrczsh和这足以让大多数个人开发的要求,我知道这不是这么简单什么vimrcvim

  • 非登录shell上使用登录原因是什么(除了消耗不同的启动文件和生命周期)?

G-M*_*ca' 38

这个想法是用户应该(至多)每个主机有一个登录 shell。(也许我应该说,每个终端每个主机一个登录 shell — 如果您同时通过多个终端登录到一台主机,您会期望有多个登录 shell。)这通常(总是?)是您获得的第一个shell登录后(因此得名)。因此,此方案允许您指定每次登录时只希望发生一次的操作以及每次启动新(交互式)shell 时希望发生的事情。

通常,您在登录后运行的每个其他 shell 都将是登录 shell 的后代(一个孩子的孩子的孩子……),因此将从登录 shell 继承许多设置(环境变量umask等)。并且,相应地,这个想法是登录初始化文件(.login.profile等)应该设置可继承的设置,并让.bashrc(或您使用的其他任何东西)处理那些不是(setshopt,非导出的shell变量, 等等。)

另一个概念是登录初始化文件(并且只有它们)应该做“繁重的工作”,即资源密集型操作。例如,您可能希望在登录时让某些进程在后台运行(但只有一个副本(实例))。您可能希望在登录时显示一些状态信息(例如dfwho),但不是每次启动新的交互式 shell 时都显示。特别是如果你有一个互动您希望每次登录时都运行的程序/对话框(即,需要您输入的程序/对话框),您可能不希望每次启动新 shell 时都运行它。作为一个极端的例子,二十年前 Solaris 将您登录到一个单一的、非图形化的、非窗口化的 shell。(我相信自那时以来,它已经改变了。)那是工作.login.profile(或其他)来启动窗口系统,用以下命令startx。(这很有用,部分是因为有多个窗口系统可用。不同的用户有不同的偏好。有些用户在不同的情况下使用不同的系统,我们在我们的对话框中有一个.profile询问“您今天想使用哪个窗口系统?”)显然,您不希望每次打开新窗口或键入时都运行它sh.

bash 除了边缘情况外,我已经很久没有使用过任何其他东西了。(例如,我用 编写脚本#!/bin/sh,所以在某些系统上,我的脚本用 运行dash,而在其他系统上,它们以bashPOSIX 模式运行。我每年运行几次csh/tcsh几分钟,看看它如何处理某些事情,或者回答问题。)如果您每天使用多个外壳(例如bashzsh),您的模式可能会有所不同。如果您的主 shell(如 中所定义/etc/passwd)是bash,您可能想要调用zsh登录 shell,然后可能调用一些zsh从属于它的交互式非登录shell。您可能应该避免让登录 shell 从属于另一个相同类型的登录 shell。

登录外壳和非登录外壳之间的区别?,OS X 终端应用程序运行登录外壳,因此典型用户通常会同时运行多个“登录外壳”。这是一种与我上面描述的模型有些不同的模型,并且可能需要用户重新考虑他.login.profile(或其他)文件。我不知道 OS X 开发人员是否已经记录了他们做出这个设计决定的理由。但我可以想象这种情况会有用。曾经有一段时间,我在登录时习惯性地打开一些 shell 窗口,我会将它们设置为不同的文本和背景颜色(通过将 ANSI 转义序列写入屏幕)以帮助我跟踪哪个是哪个。终端颜色是一个例子,它不是由孩子的孩子继承的,但确实存在于窗口中。所以这是你每次启动一个新的终端窗口时都想做的事情,但不是每次启动一个新的交互式 shell 时。