区分交互式登录和非交互式非登录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。 如果sshstdin不是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由脚本运行,不需要用户输入。