我试图区分这四个术语login、non-login、interactive 和 non-interactive:
- 交互式 - 登录外壳
- 交互式 - 非登录 shell
- 非交互 - 登录 shell
- 非交互式 - 非登录外壳
据我了解
交互式-非登录shell:启动系统,登录系统并打开终端和
非交互式-登录shell:telnet到系统并登录
但是交互式登录 shell 呢?
它是否登录系统,打开虚拟终端并登录?和
非交互式 - 非登录 shell,它是否在 crontab 中运行自动化脚本?
您似乎唯一真正的误解是关于什么构成了非交互式登录 shell。
简要说明(有关详细信息,请参见此处),并附有示例:
交互式登录 shell:例如,您可以通过
ssh
. Ctrl或者,您可以访问本地机器 ( ++ Alt)上的 ttyF1并在那里登录。交互式非登录外壳:打开一个新终端。
非交互式非登录外壳:运行脚本。所有脚本都在它们自己的子 shell 中运行,并且这个 shell 不是交互式的。它仅打开以执行脚本,并在脚本完成后立即关闭。
非交互式登录shell:这是非常罕见的,你不太可能遇到它。一种启动方式是
echo command | ssh server
. 当ssh
在没有命令的情况下启动时(ssh
而不是在远程 shell 上ssh command
运行command
),它会启动一个登录 shell。如果 的stdin
不是ssh
tty,它会启动一个非交互式 shell。这就是为什么echo command | ssh server
会启动一个非交互式登录 shell。您也可以从bash -l -c command
.如果你想玩这个,你可以测试各种类型的 shell,如下所示:
这个shell是交互式的吗?
检查
$-
变量的内容。对于交互式 shell,它将包括i
:这是登录外壳吗?
没有可移植的方法来检查这一点,但是对于 bash,您可以检查是否
login_shell
设置了该选项:将所有这些放在一起,这是每种可能的外壳类型之一:
从本质上讲,shell 是否登录、是否交互都很重要,原因只有一个:
初始化文件和默认选项设置取决于 shell 是否登录和交互。
相应地,shell 是否登录或交互仅取决于使用的调用- 确切的命令名称和选项。
这两个属性在其他方面是正交的——shell 是否登录与确定它是否是交互式的无关。
如果其中任何一个为真,Bash 将启动一个登录 shell:
argv[0]
,它被调用的命令的名称,以-
-l
指定类似地,如果其中任何一个为真,bash 将启动一个交互式 shell:
bash some/file
)或要运行的命令字符串(bash -c 'foo'
)(实际情况有点复杂,请参阅手册)-i
指定值得注意的是(并且自相矛盾),后者意味着
bash -ic 'foo'
启动一个交互式外壳。因此,以下启动了一个登录的交互式 shell,即使它没有任何交互性,并且调用与登录无关:
通过控制台或 GUI 登录会启动登录 shell(或者可能不会),这完全是使用适当调用的登录过程的效果。
条件和效果在bash 手册的 Startup Files 部分中有详细描述。
一个主要的混淆来源是“登录”外壳还有另一个常见的含义:
用户的登录 shell 是在该用户的
passwd
条目中定义的 shell(可能来自/etc/passwd
、LDAP 或其他来源)。程序、SSH 等将
login
这个 shell 作为登录shell 启动,这在答案的其余部分意味着 --
通常在命令名称中带有前导。如果你想特别混淆,你可以说:一些登录进程将用户的登录 shell 作为登录 shell 启动。
请注意,GUI 登录启动登录 shell 纯粹是因为开发人员认为它很方便 - LightDM 在登录时运行一个脚本,该脚本显然不是交互式的,并且当然不依赖于用户的登录 shell(在第二种意义上)。但是,不要依赖显示管理器启动登录 shell - 并非所有人都这样做,并且在 Wayland 和 GNOME 上,登录过程根本不使用 shell 脚本。
登录外壳:
交互式外壳:
简单地说:交互式 shell 需要用户输入,而非交互式 shell 由脚本运行,不需要用户输入。
接受的答案中缺少一类外壳(非交互式,带有 hBc 选项的登录外壳)。与带有 hBs 选项的选项不同,它通常用于在 ssh 会话中执行命令。看看,比较 4 和 5。我把它和其他人一起包括在内。
什么是登录 Shell?
它在登录会话期间按以下顺序从第一个可用文件(如果存在)读取并执行命令:
它在注销期间按以下顺序读取并执行所有文件(如果存在)的命令:
注意:调用登录文件(仅第一个可用文件)和注销文件(所有文件)的区别。
注意:
~/.bashrc
在登录 shell 会话期间执行文件命令时总是会出现混淆。通常,~/.bashrc
文件中的命令不应在登录 shell期间执行。但是,如果发生这种情况,那是因为~/.bash_profile
文件中包含~/.bashrc
文件。验证您的~/.bash_profile
文件。这是基于 Fedora 的 Linux 发行版中的常见行为。什么是免登录外壳?
它从用户特定的设置文件中读取并执行命令:~/.bashrc
什么是非交互式会话?
BASH_ENV
它从变量中读取并执行命令。它也是一种控制非交互式会话行为的方法。注意:
BASH_ENV
必须包含 shell 脚本文件的完整路径。注意: ssh 远程非交互式 shell 会话不会读取
BASH_ENV
. 相反,它读取~/.bashrc
远程系统中远程用户的文件。注意:
ssh
远程会话不会从登录 shell (~/.bash_profile) 中提到的文件执行命令。这将不起作用:
这将起作用:因为,
.bashrc
属于假定为远程用户的当前用户,并且在此示例中假定远程系统为 localhost。如何控制登录shell的行为?
在登录 shell 中使用
--noprofile
选项禁用从上述文件中读取命令。如何控制 no-login shell 的行为?
--rcfile
选项指定用户特定的 rc 文件--norc
选项禁用从上述文件中读取命令我想提一下,您可以通过以下方式启动交互式登录 shell:
sudo /bin/login
并输入您的凭据exec -l /bin/bash
su -
此外,您可以通过键入检查(在 bash 中)shell 是否登录
echo $0
,如果输出以 dash 开头-
,则它是登录 shell。