是否有可能存在非交互式登录 shell?

11 startup bash login bashrc

在解释这个流程图时

在此处输入图片说明

我在 man bash 中发现:

当 bash 作为交互式登录 shell 或作为具有 --login 选项的非交互式 shell 调用时,它首先从文件 /etc/profile 读取并执行命令(如果该文件存在)。

这表明交互式登录shell 读取/etc/profile(没有 --noprofile)

此外,选项为read 的非交互式shell--login/etc/profile

这似乎留下一些可能的登录炮弹(其中$0一个开始-),其被非交互式(运行脚本,也许就这么简单date)可能无法读取(源)/etc/profile

确认或否认这个想法:

首先,我尝试使用su -l -,它以 a-作为第一个字符启动登录外壳,但我未能使其非交互式(并且能够提供测试来探测它)。

调用类似的东西

$ bash -c 'date' -bash
Run Code Online (Sandbox Code Playgroud)

不报告为登录 shell(即使第一个字符是 a -)。

试试这个来揭示细节:

   $ bash -c 'echo "$0 $- ||$(shopt -p login_shell)||";date' -bash
      -bash hBc ||shopt -u login_shell||
      Fri Aug 19 06:32:31 EDT 2016
Run Code Online (Sandbox Code Playgroud)

$0a-作为第一个字符,值中没有i(交互)$-但不报告为 a login_shell(-u)。在这种情况下,未读取 /etc/profile,但我不确定这是正确的测试。


在这个答案中还提到了“罕见的非交互式登录 shell” 但对这个问题不够具体。


这家伙结论是,/etc/profile总是读。

阅读汇总表:交互式和非交互式登录shell阅读 /etc/profile


并且,如果此页面的示例是正确的:

Some examples

$ su bob                   # interactive non-login shell
$ su - bob                 # interactive login shell
$ exec su - bob            # interactive login shell
$ exec su - bob -c 'env'   # non-interactive login shell
$ ssh bob@example.com      # interactive login shell, `~/.profile`
$ ssh bob@example.com env  # non-interactive non-login shell, `~/.bashrc`
Run Code Online (Sandbox Code Playgroud)

对已阅读exec su - bob -c 'env'报告的测试/etc/profile


简而言之:

是否可以使用非交互式登录shell(不使用 --login 或 -l 调用)?

如果为真,它是否正在读取/etc/profile文件?

如果上述情况属实,我们必须得出结论,所有登录 shell [交互式(或非交互式)] 都读取 /etc/profile(没有--noprofile选项)。

注意:要检测 /etc/profile 是否正在被读取,只需在文件的最开头添加以下命令:

echo "'/etc/profile' is being read"
Run Code Online (Sandbox Code Playgroud)

Gil*_*il' 2

非交互式登录 shell 并不常见,但也是可能的。如果您将第零个参数(通常是可执行文件的名称)设置为以 a 开头的字符串来启动 shell -,则它是一个登录 shell,无论它是否是交互式的。

$ ln -s /bin/bash ./-bash
$ echo 'shopt -p login_shell; echo $-' | HOME=/none PATH=.:$PATH -bash
shopt -s login_shell
hB
Run Code Online (Sandbox Code Playgroud)

您的尝试bash -c date -bash不起作用,因为这并没有告诉 shell 是登录 shell:第零个参数是bash,而不是-bash。bash 启动后,它将变量设置$0为 ,-bash而不是第 0 个参数,但第 0 个参数才是重要的。

您可以使用su -l或运行非交互式登录 shell su -,但您需要安排标准输入不是终端,同时仍能够获得授权(无需输入密码,或将密码安排在开头)输入)。使用 sudo: run 来获取存在凭证可能会更容易sudo true,然后在凭证仍然有效时运行echo 'shopt -p login_shell; echo $-' | sudo -i

另请参阅登录 Shell 和非登录 Shell 之间的区别?