# Chroot (简体中文)

From ArchWiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
翻译状态：本文是 Change_Root 的翻译。上次翻译日期：2017-12-12。如果英文版本有所更改，则您可以帮助同步翻译。

Chroot 就是变更当前进程及其子进程的可见根路径。变更后，程序无法访问可见根目录外文件和命令。这个目录叫作 chroot jail。

## 原因

切换根目录通常为了系统维护，例如重装引导程序或者重置遗忘的密码。

- 重新安装 bootloader.
- 重建 initramfs 镜像.
- 更新或 降级软件包.
- 重置 忘记的密码.
- 在干净的 chroot 中构建软件包：DeveloperWiki:Building in a clean chroot.

参阅 Wikipedia:Chroot#Limitations.

## 必要条件

- root 权限
- 另一个 linux 环境，例如 liveCD、USB 闪存介质或者一个已经安装的另一个 linux 发行版。
- 匹配的架构，chroot 前后的环境架构要一致(例如，都是 i686 或 x86_64)。可以用以下命令查看当前环境的架构

      uname -m

- 提前加载 chroot 环境需要的内核模块
- 如果需要 swap， chroot 前先启用 swap （`swapon /dev/sdxY`）
- 如果需要网络，chroot 之前先建立好网络连接。

## 用法

注意：

- 有些systemd 工具无法在 chroot 中运行，例如 localectl 和 timedatectl，因为这些程序需要可用的 dbus 连接. [1]
- 新的 root (`/`) 所在的文件系统必须是可用访问的状态(提前解密、挂载).

有两种使用 chroot 的方式：

### 使用 arch-chroot

`arch-chroot` bash 脚本是软件包 arch-install-scripts 的一部分，在运行 `/usr/bin/chroot` 前，这个脚本会挂载 `/proc` api 文件系统，建立可用的 `/etc/resolv.conf`。

进入 chroot

    # arch-chroot /location/of/new/root

例如在 安装指南 中，chroot 到 `/mnt`:

    # arch-chroot /mnt

退出 chroot:

    # exit

#### 运行一个命令并退出

用下面命令在 chroot 中运行一个命令并退出：

    # arch-chroot /location/of/new/root mycommand

例如要在 `/mnt/arch` 中运行 `mkinitcpio -p linux` 并退出:

    # arch-chroot /mnt/arch mkinitcpio -p linux

### 使用 chroot

警告： 使用 `--rbind` 选项时，将无法卸载某些 `dev/` 和 `sys/` 的子目录，用 `umount -l` 卸载将会破坏会话并需要重启，所以请尽可能使用 `-o bind`。

作为 root 挂载 api 文件系统：

    # cd /location/of/new/root
    # mount -t proc proc proc/
    # mount --rbind /sys sys/
    # mount --rbind /dev dev/

可选挂载:

    # mount --rbind /run run/

如果已经建立了一个网络连接并且想在 chroot 环境中继续使用，将 DNS 服务器配置复制到新环境：

    # cp -L /etc/resolv.conf etc/resolv.conf

chroot 到新环境中并启用指定 shell

    # chroot /mnt/arch /usr/bin/bash

注意：

- 如果遇到错误 `chroot: cannot run command '/bin/bash': Exec format error`，很可能两个环境架构不匹配。
- 如果遇到错误 `chroot: '/usr/bin/bash': permission denied`,用执行权限重新挂载: `mount -o remount,exec /mnt/arch`。

（可选）加载 Bash 配置文件(`~/.bashrc` 和 `/etc/bash.bashrc`)，运行：

    # source ~/.bashrc
    # source /etc/profile

或创建一个独特的提示符来区别你的chroot环境：

    # export PS1="(chroot) $PS1"

退出 chroot 环境：

    # exit

然后卸载临时文件系统:

    # cd /
    # umount --recursive /location/of/new/root

如果出现 `/mnt`(或其它任何分区) is busy, 这可能意味着：

- chroot环境中残留了一个运行的程序或者还有分区没有被卸载，退出程序并用 `mount` 查找未卸载的分区。
- 如果你仍然不能卸载分区，使用`--force`选项：

      # umount -f /mnt

  ， 或使用 `umount --lazy` 直接释放挂载。这是，请立即重启系统以避免不一致的状态导致冲突。

## 在 chroot 中运行图形程序

如果系统上运行了X，可以在 chroot 环境启动图形应用。

为了chroot环境能连接到你的X服务器，在X服务器中打开一个终端(例如，在用户当前登录的桌面中)，然后运行如下命令给任何人连接到用户X服务器的权限：

    $ xhost +local:

然后，从chroot环境中将应用指向你的X服务器，将chroot中的DISPLAY环境变量设定成和拥有X服务器的用户DISPLAY变量相匹配。例如，运行：

    $ echo $DISPLAY

作为拥有X服务器的用户查看DISPLAY的值。如果是“:0”(例如是)，然后在chroot环境中运行

    # export DISPLAY=:0

现在就可以从chroot命令行启动图形界面应用

## 不使用 root 权限

Chroot 需要 root 权限，有时用户并没有这个权限，下面工具可用实现类似的功能：

### PRoot

PRoot 可用在没有 root 权限的情况下，用 `mount --bind` 设置可见根目录，这样可用为不同的 CPU 架构编译程序。这个程序的缺点是文件属于主机系统。可用用 `--root-id` 选项解决一部分问题。

### Fakechroot

fakechroot 是一个拦截 chroot 调用并伪造结果的程序。用 fakeroot 可用为普通用户伪造一个 chroot 环境：

    # fakechroot fakeroot chroot ~/my-chroot bash

## 参阅

- Chroot 基础

Category:

- System recovery (简体中文)