区分交互式登录和非交互式非登录shell
我试图区分这四个术语登录,非登录,交互和非交互 :
- 交互式 – 登录shell
- 交互式 – 非登录shell
- 非交互式 – 登录shell
- 非交互式 – 非登录shell
我认为
交互式 – 非登录shell :启动系统,登录系统并打开终端和
非交互式 – 登录shell :telnet到系统并登录
但是交互式登录shell呢?
它是否登录系统,打开虚拟终端并登录? 和
非交互式 – 非登录shell,是否在crontab中运行自动脚本?
您似乎唯一真正的误解是关于什么构成非交互式登录shell。
简要介绍(详见此处 ),举例:
-
交互式登录shell:您通过例如
ssh
登录到远程计算机。 或者,您可以在本地计算机上下载一个tty( Ctrl + Alt + F1 )并登录。 -
交互式非登录shell:打开一个新的终端。
-
非交互式非登录shell:运行脚本。 所有脚本都在自己的子shell中运行,而且这个shell不是交互式的。 它只会打开以执行脚本并在脚本完成后立即关闭。
-
非交互式登录shell:这是非常罕见的,你遇到它是不可思议的。 启动一种方法是
echo command | ssh server
echo command | ssh server
。 当没有命令启动ssh
(所以ssh
而不是ssh command
将在远程shell上运行command
)它启动一个登录shell。 如果ssh
的stdin
不是tty,则启动非交互式shell。 这就是echo command | ssh server
echo command | ssh server
将启动一个非交互式登录shell。 您也可以使用bash -l -c command
启动一个。
如果你想玩这个,你可以测试各种类型的shell如下:
-
这个shell是交互式的吗?
检查
$-
变量的内容。 对于交互式shell,它将包括i
:## Normal shell, just running a command in a terminal: interacive $ echo $- himBHs ## Non interactive shell $ bash -c 'echo $-' hBc
-
这是一个登录shell吗?
没有可移植的方法来检查这个,但是对于bash,你可以检查是否设置了
login_shell
选项:## Normal shell, just running a command in a terminal: interacive $ shopt login_shell login_shell off ## Login shell; $ ssh localhost $ shopt login_shell login_shell on
将所有这些放在一起,这是每种可能类型的shell之一:
## Interactive, non-login shell. Regular terminal $ echo $-; shopt login_shell himBHs login_shell off ## Interactive login shell $ bash -l $ echo $-; shopt login_shell himBHs login_shell on ## Non-interactive, non-login shell $ bash -c 'echo $-; shopt login_shell' hBc login_shell off ## Non-interactive login shell $ echo 'echo $-; shopt login_shell' | ssh localhost Pseudo-terminal will not be allocated because stdin is not a terminal. hBs login_shell on
基本上,无论shell是否登录,交互式或不重要的原因只有一个:
初始化文件和默认选项集取决于shell是否登录以及是否具有交互性。
相应地,shell是否登录或交互是否仅取决于所使用的调用 – 确切的命令名称和选项。
这两个属性是正交的 – 无论shell是否登录都无法确定它是否具有交互性。
如果其中任何一个为真,Bash会启动一个登录shell:
-
argv[0]
,它被调用的命令的名称,以-
开头-
- 指定了
-l
选项
类似地,如果其中任何一个为真,bash会启动一个交互式shell:
- 它没有指定要执行的文件(即命令不是
bash some/file
)或要运行的命令字符串(bash -c 'foo'
)(实际条件有点复杂,请参阅手册) -
-i
选项已指定
值得注意的是(反之亦然),后者意味着bash -ic 'foo'
启动了一个交互式shell。
所以下面开始一个登录,交互式shell,即使它没有任何关于它的交互,并且调用与登录无关:
bash -lic true
通过控制台或GUI登录启动登录shell(或者可能不是)完全是使用适当调用的登录过程的影响。
有关条件和效果的详细信息,请参阅bash手册的“启动文件”部分 。
混淆的一个主要原因是“登录”shell还有另一个常见含义:
用户的登录shell是在该用户的passwd
条目中定义的shell(可能来自/etc/passwd
,LDAP或其他来源)。
login
程序,SSH等等,通常在命令名称中使用意义上的其他答案启动此shell作为登录 shell。 如果你想特别困惑,你可以说:
某些登录进程以登录shell的身份启动用户的登录shell。
请注意,GUI登录启动登录shell纯粹是因为开发人员认为这很方便–LingDM在登录时运行一个脚本,这显然不是交互式的,当然也不依赖于用户的登录shell(在第二种意义上)。 不要依赖显示管理器启动登录shell,但并非所有这些都可以,并且在Wayland和GNOME上,登录过程根本不使用shell脚本。
登录shell:
我们登录会话时在我们的用户ID下执行的第一个进程。 登录过程告诉shell表现为具有约定的登录shell:传递参数0,它通常是shell可执行文件的名称,前缀为“ – ”字符
交互式shell:
从tty上的用户输入读取命令。 除此之外,这样的shell在激活时读取启动文件,显示提示,并默认启用作业控制。 用户可以与shell交互。 运行脚本的shell始终是非交互式shell。
简单地说:交互式shell需要用户输入,而非交互式shell由脚本运行,不需要用户输入。