bash 如何知道它是如何被调用的?

cwd*_*cwd 7 bash login ubuntu jails

我已经安装jailkitUbuntu 12.04,我已经建立了一个用户的shell来/bin/bash-但是当它被调用运行/etc/bash.bashrc,而不是/etc/profile

如果您以前没有使用jailkit过这里是它的要点:

  1. 系统根目录的“监禁”版本在某处创建,例如 /home/jail
  2. 被监禁的用户主目录移动到该文件夹​​内,如 /home/jail/home/testuser
  3. 相关配置文件被复制到 /home/jail/etc/ - 包括有限的 /etc/passwd
  4. 您希望允许访问的程序被复制到相应的目录中,例如 /bin/bash
  5. 当一个被监禁的用户登录时,他们被 chroot 到 /etc/jail/ 并且看不到上面的任何文件

所以我有一个testuser这样的条目/etc/passwd

testuser:x:1002:1003::/home/jail/./home/testuser:/usr/sbin/jk_chrootsh
Run Code Online (Sandbox Code Playgroud)

在文件中/home/jail/etc/passwd有一个条目,如:

testuser:1001:1003::/home/testuser:/bin/bash
Run Code Online (Sandbox Code Playgroud)

我已经阅读了bash(1),所以我认为问题在于 bash 认为它没有被作为登录 shell 调用:

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

我知道这bash实际上是被调用的,/usr/sbin/jk_chrootsh但我不明白如何bash确定它是什么类型的外壳,以及它应该运行哪组启动文件。

我想看看我是否可以解决这个问题 - 但我不明白:

bash 如何知道它是如何被调用的?

ps:我也看了,login(1)运气不好。

Gil*_*il' 8

通常 bash 知道它是一个登录 shell,因为当登录程序调用它时,它告诉 bash 它的名称是-bash. 该名称在argv[0]第零个命令行参数中,通常是用户调用程序的方式。最初的连字符是告诉 shell 它是一个登录 shell 的约定。如果您向 Bash 传递选项--login-l. 请参阅登录 Shell 和非登录 Shell 之间的区别?更多细节。

从 Jailkit 2.16 开始,jk_chrootsh读取 shell 的绝对路径以从各种来源调用,并将此路径作为argv[0]传递,并将其自己的命令行参数传递给该 shell。在通常的用例 wherejk_chrootsh本身使用 in 时/etc/passwd,无法传递诸如-l. 由于绝对路径不以 开头-,因此无法jk_chrootsh调用登录shell,除非使用一个微小的中间程序。

#include <unistd.h>
int main () {
    execl("/bin/bash", "-bash", NULL);
    return 127;
}
Run Code Online (Sandbox Code Playgroud)

我本来希望jk_chrootsh有一种简单的方法来调用登录 shell。我建议提出功能请求。


Sté*_*las 6

login调用用户的登录命令/shell,argv[0]-. 外壳检查它们argv[0]以确定它们是否被称为登录外壳。

正如@slm 所说,它在bash手册的“调用”部分中有明确说明。

此外,一些炮弹一样cshtcshkshzshyashbash和一些Almquist外壳的变体都支持-l启用该选项login模式,而无需打成一片的第一个参数。这不是由 使用login,但如果您想从难以使用任意argv[0]. 我已经看到它被图形登录管理器使用。