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

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

在口译中这个流程图

在此输入图像描述

我在 man bash 中发现:

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

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

还,非交互式带有选项--loginread 的shell/etc/profile

这似乎留下了一些可能登录shell(其中$0以 a 开头-非交互式(运行脚本,可能像这样简单date)可能无法读取(源)/etc/profile

确认或否定这个想法:

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

调用类似的东西

$ bash -c 'date' -bash

不报告为登录 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

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


还提到了“罕见的非交互式登录 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 [email protected]      # interactive login shell, `~/.profile`
$ ssh [email protected] env  # non-interactive non-login shell, `~/.bashrc`

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


简而言之:

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

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

如果上述情况为真,我们必须得出结论:全部登录 shell [交互式(或非交互式)] 读取 /etc/profile(无--noprofile选项)。

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

echo "'/etc/profile' is being read"

答案1

我见过图形登录环境可以:

exec "$SHELL" -l -c 'exec start-window-or-session-manager'

或等价于:

exec -a "-$SHELL" "$SHELL" <<EOF
exec start-window-or-session-manager
EOF

以便读取并应用会话初始化文件(例如~/.profile类似 Bourne 的 shell(以及某些 shell 中的相应文件))。/etc

第一个不适用于所有 shell。-l受大量 shell 支持,但不是全部,并且在某些 shell(例如csh/ tcsh)上不能与 一起使用-c。不过,所有 shell 都可以理解argv[0]存在的第一个字符-,因为它login用来告诉 shell 它们是登录 shell。

在第二种情况下,该 shell 的 stdin 不是设备tty<<由临时常规文件或取决于 shell 的管道实现),因此 shell 不是交互式的(交互的定义是当人类交互时)用它)。

答案2

是的,可以使用非交互式登录 shell

$ head -1 /etc/profile
echo PROFILE BEING READ

$ echo echo hello | su -
PROFILE BEING READ
stdin: is not a tty
hello

$

答案3

非交互式登录 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

您的尝试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 之间的区别?

答案4

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

是的。

$ (exec -a '-' bash -c 'shopt -q login_shell && echo login shell')

但是,请注意,除非给出参数,/etc/profile否则不会用于非交互式登录 shell 。--login

调用非交互式登录 shell 的常见习惯用法是:

$ su - someuser -c somecommand

/etc/profile但这会遇到一个没有被执行的事实。

可以更改此行为,但它涉及通过取消注释中找到的选项来在编译时自定义 Bash 源代码配置-top.h

/* Define this to make non-interactive shells begun with argv[0][0] == '-'
run the startup files when not in posix mode. */
/* #define NON_INTERACTIVE_LOGIN_SHELLS */

当我研究了这个su异常现象,我发现其他shell包括zshdash没有这个差异。

相关内容