我假设以下内容会起作用:
mkdir /tmp/chrootTest # Create chroot folder.
mkdir /tmp/chrootTest/bin # Create `/bin` in the chroot folder.
sudo mount -B /bin /tmp/chrootTest/bin/ # Bind-mount the real system's `/bin` to the chroot's `/bin`.
sudo chroot /tmp/chrootTest/ /bin/bash # Execute (open) `/bin/bash` in the chroot.
然而最后一个命令产生:
chroot: failed to run command ‘/bin/bash’: No such file or directory
我还尝试复制/bin
并/tmp/chrootTest/bin
授予其完全权限。然而,这也行不通。
/bin/bash
如果看到一条错误消息,通知我无法在其非常基本的 chroot 中工作,因为无法找到其他文件,我不会完全感到惊讶。然而,打印的错误消息令人惊讶,因为该文件显然存在。
为什么会发生这种情况?在 chroot 中成功打开 bash 需要什么?
答案1
如果/bin/bash
是具有共享库依赖项的二进制文件,则需要能够在 chroot 内解析这些依赖项。
在我的系统上:
$ ldd $( command -v bash )
/usr/local/bin/bash:
Start End Type Open Ref GrpRef Name
0000115f08700000 0000115f08a0c000 exe 1 0 0 /usr/local/bin/bash
00001161f6a2e000 00001161f6c88000 rlib 0 1 0 /usr/lib/libtermcap.so.14.0
00001161bc41e000 00001161bc629000 rlib 0 1 0 /usr/local/lib/libintl.so.6.0
000011614b1de000 000011614b4dd000 rlib 0 2 0 /usr/local/lib/libiconv.so.6.0
00001161bd091000 00001161bd35b000 rlib 0 1 0 /usr/lib/libc.so.89.2
000011612ef00000 000011612ef00000 rtld 0 1 0 /usr/libexec/ld.so
相比之下:
$ ldd $( command -v sh )
/bin/sh:
Start End Type Open Ref GrpRef Name
000007ca3c446000 000007ca3c6c6000 dlib 1 0 0 /bin/sh
我使用的是 OpenBSD。 Linux 系统上的输出格式ldd
会有所不同,但 Linux 上也应该显示相同的基本信息(共享哪些库以及它们在哪里)。
当我尝试使用非常简单化的 chroot 仅包含/bin/sh
和/bin/bash
(doas
是 OpenBSD 的“sudo
替代品”):
$ doas chroot -u kk t /bin/sh
/bin/sh: No controlling tty (open /dev/tty: No such file or directory)
/bin/sh: warning: won't have full job control
$ /bin/bash
Abort trap
请注意,我确实得到了一个 shell ( /bin/sh
),但/bin/bash
失败了。该错误与您的错误不同,但我认为原因相同。/bin/bash
直接使用该命令执行chroot
只会给出一个单词“Abort”消息,同样,可能是由于库存在同样的问题。
结论: chroot 需要至少包含系统的最小安装,包括运行其中的可执行文件所需的设备文件和库。
Linux上“没有这样的文件或目录”错误的解释:
我有点困惑为什么在 Linux 上错误是“没有这样的文件或目录”,所以我通过strace
.
execve()
应该执行 shell 的调用返回 ENOENT :
execve("/bin/bash", ["/bin/bash"], [/* 13 vars */]) = -1 ENOENT (No such file or directory)
......所以我认为这是有问题的发现/bin/bash
。然而,阅读execve(2)
手册后,我发现:
ENOENT
文件文件名或脚本或ELF解释器不存在,或者找不到文件或解释器所需的共享库。
那么就这样吧。
答案2
确保您的安装系统和用于 chroot 的介质具有相同的架构。
你挂载到/mnt的分区是你安装系统时的/分区吗?
我用这种方式chroot。
对于 ext* 文件系统。
sudo mount /dev/sdxY /mnt
对于单独的 /boot BIOS 模式分区
sudo mount /dev/sdzY /mnt/boot
对于 efi 模式
sudo mount /dev/sdwY /mnt/boot/efi
挂载vituelle文件系统
for dir in /dev /dev/pts /proc /sys /run; do sudo mount --bind $dir /mnt/$dir; done
对于网络访问
cp -a /etc/resolv.conf /mnt/etc/resolve.conf
然后
sudo chroot /mnt /bin/bash
但我只在 Debian 和 Ubuntu 上使用它。
答案3
只需将示例代码修改为以下内容:(对我有用)
mkdir /tmp/chrootTest
mkdir /tmp/chrootTest/bin
mkdir /tmp/chrootTest/lib
mkdir /tmp/chrootTest/lib64
sudo mount -B /bin /tmp/chrootTest/bin/
sudo mount -B /lib /tmp/chrootTest/lib/
sudo mount -B /lib64 /tmp/chrootTest/lib64/
sudo chroot /tmp/chrootTest/ /bin/bash