区分交互式登录和非交互式非登录外壳


25

我试图区分以下四个术语:登录,非登录,交互式和非交互式

  • 交互式-登录外壳
  • 交互式-非登录外壳
  • 非交互式-登录外壳
  • 非交互式-非登录外壳

据我了解,
交互式-非登录Shell:启动系统,登录到系统并打开终端,并且
非交互式-登录Shell:通过telnet进入系统并登录

但是交互式的登录外壳又如何呢?
它是否登录到系统,打开虚拟终端并登录?并且
非交互-非登录外壳,它在crontab中运行自动化脚本吗?

Answers:


38

您似乎唯一真正的误解是关于什么构成非交互式登录外壳。

简要地(请参阅此处以获取更多详细信息),并带有示例:

  • 交互式登录外壳:例如,您通过登录到远程计算机ssh。另外,您可以在本地计算机(Ctrl+ Alt+ F1)上的tty上登录。

  • 交互式非登录外壳:打开一个新终端。

  • 非交互式非登录外壳程序:运行脚本。所有脚本都在各自的子外壳中运行,并且该外壳不是交互式的。它仅会打开以执行脚本,并在脚本完成后立即关闭。

  • 非交互式登录外壳程序:这非常罕见,您不太可能遇到它。一种启动方式是echo command | ssh server。如果ssh在没有命令的情况下启动(ssh而不是在远程外壳程序上ssh command运行command),它将启动登录外壳程序。如果stdinof的ssh不是tty,它将启动非交互式shell。这就是为什么echo command | ssh server将启动非交互式登录Shell的原因。您也可以从开始bash -l -c command

如果您想解决这个问题,可以按如下所示测试各种类型的shell:

  • 这个外壳是交互式的吗?

    检查$-变量的内容。对于交互式外壳,它将包括i

    ## Normal shell, just running a command in a terminal: interacive
    $ echo $-
    himBHs
    ## Non interactive shell
    $ bash -c 'echo $-'
    hBc
  • 这是登录外壳吗?

    没有可移植的方法检查这个,但是,对于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

放在一起,这是每种可能的外壳类型之一:

## 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

我想清除以下几点:1)对我来说,登录gui意味着启动系统,登录到系统并打开终端2)做telnet或ssh是交互式登录外壳,这意味着我给出的示例 non-interactive login shell错误。
雏菊

@daisy感谢您的澄清;答案已编辑。
terdon

好的,gui是无关紧要的交互式非登录外壳:只需通过telnet或ssh在本地或远程打开一个新终端
雏菊

@daisy是的,听起来不错。但是也请仔细阅读Muru的答案,因为从本质上讲,这解释了语义上的问题,并且仅影响shell读取哪些启动文件。另请参阅此处,以获取有关不同外壳类型的更全面概述。
terdon

非交互式登录外壳并不少见,例如git使用它们,即IIRC。
夸斯加

6

从本质上讲,无论shell是否登录,交互性都取决于一个原因:

初始化文件和默认选项的设置取决于外壳程序是否登录以及是否交互。

相应地,shell是登录还是非交互式还是仅取决于所使用的调用 -确切的命令名称和选项。

否则,这两个属性是正交的-外壳是否登录与确定外壳是否互动无关。

如果满足以下任一条件,Bash将启动登录Shell:

  • argv[0],被调用为的命令名称,以a开头 -
  • -l选项已指定

类似地,如果满足以下任一条件,则bash将启动一个交互式shell:

  • 它没有指定要执行的文件(即,命令不是bash some/file)或命令字符串来运行(bash -c 'foo')(实际情况比较复杂,请参见手册)
  • -i选项已指定

值得注意的是(并且自相矛盾的是)后者暗示着bash -ic 'foo'启动了一个交互式外壳。

因此,即使它与交互无关,并且调用与登录无关,也可以通过以下操作启动登录交互shell:

bash -lic true

通过控制台或GUI登录会启动登录外壳程序(或可能不会),这完全是使用适当的调用进行登录过程的结果。

bash手册中“启动文件”部分详细描述了这些条件和效果。


造成混淆的一个主要原因是“登录” shell还有另一种常见含义:

用户的登录外壳程序是该用户passwd条目中定义的外壳程序(可能来自/etc/passwd,LDAP或其他来源)。

login程序,SSH等启动这个shell作为登录在回答其余意味着感壳-以领先-的命令名称,通常。如果您想让自己特别困惑,可以说:

某些登录过程会将用户的登录外壳作为登录外壳启动。

请注意,GUI登录纯粹是因为开发人员认为方便而启动了登录外壳程序-LightDM在登录时运行脚本,该脚本显然不是交互式的,并且当然不依赖于用户的登录外壳程序(从第二个意义上来说)。但是,不要依赖于显示管理器启动登录外壳程序-并非所有人都可以,并且在Wayland和GNOME上,登录过程根本不使用外壳程序脚本。


3

登录外壳:

登录到会话时,将在用户ID下执行的第一个过程。登录过程告诉外壳程序以登录外壳程序的方式遵循以下约定:传递参数0(通常是外壳程序可执行文件的名称),并带有“-”字符

交互式外壳:

从tty上的用户输入读取命令。除其他外,此类外壳在激活时读取启动文件,显示提示并默认启用作业控制。用户可以与外壳进行交互。运行脚本的外壳程序始终是非交互式外壳程序。

简而言之:交互式外壳程序需要用户输入,而非交互式外壳程序由脚本运行,不需要用户输入。


因此,给出的示例是正确的。
雏菊

是的,菊花在正确的位置。
George Udosen '17

1
@雏菊不!GUI绝对与它无关。这是关于命令行外壳程序,而不是图形外壳程序(也存在但它们是不同的野兽)。
terdon

1
@George不,有两个错误:通过GUI登录不会启动登录Shell(或任何其他相关外壳),并且通过telnet登录到远程系统将启动telnet Shell,但是通过ssh启动交互式登录贝壳。
terdon

1
@乔治实际上,我站得住了。一些GUI登录管理器可能会启动登录外壳以进行读取.profile(我以为他们只是.profile手动提供资源,但我可能错了)。
terdon

0

我想提一下,您可以通过以下方式启动交互式登录Shell:

  1. 执行sudo /bin/login并输入您的凭证
  2. 执行中 exec -l /bin/bash
  3. 执行中 su -
  4. 就像上面说的答案一样,使用ssh并登录到远程计算机

另外,您可以通过键入(以bash格式)检查外壳是否登录,echo $0以及输出是否以破折号开头-,则它是登录外壳。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.