chroot - Arch Linux 中文维基

跳至內容

# chroot

出自 Arch Linux 中文维基

翻譯狀態：

- 本文（或部分內容）譯自 Chroot，最近一次同步於 2022-05-10，若英文版本有所更改，則您可以幫助同步與翻譯更改的內容。
- 您可以在 ArchWiki 的對應頁面找到本文翻譯的原始修訂歷史。
- 本文可能與英文原文存在出入。

Chroot 是一種修改當前進程及其子進程的可見根目錄的操作。修改後，進程將不能訪問該環境目錄樹以外的任何文件和命令，這種修改後的環境叫作 chroot jail（直譯為 chroot 監獄）。

## 原因

改變根目錄通常是為了在無法啟動或登錄的系統上進行系統維護，例如：

- 重新安裝 bootloader。
- 重建 initramfs 鏡像。
- 升級或降級軟體包。
- 重置忘記的密碼。
- 在在乾淨的 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 中運行，例如 hostnamectl、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`。

在下面的例子中，`/location/of/new/root` 代指新的根目錄所在的文件夾。 首先，臨時掛載 API 文件系統：

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

可選掛載:

    # mount --rbind /run run/

如果正運行在 UEFI 系統，則還需要能夠訪問 EFI 變量，不然在安裝 GRUB 時會得到類似這樣的消息：`UEFI variables not supported on this machine`：

    # mount --rbind /sys/firmware/efi/efivars sys/firmware/efi/efivars/

如果已經建立了一個網絡連接並且想在 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 /location/of/new/root`。
  - 如果以上方式無效，那麼請確保新環境的基礎組件完整（如果是 Arch 根目錄，請嘗試 `paccheck --root=/location/of/new/root --files --file-properties --md5sum glibc filesystem`，來自 pacutils包）。

（可選）加載 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環境中殘留了一個運行的程序或者還有分區沒有被卸載，退出程序並用 `findmnt -R /location/of/new/root` 查找然後卸載未卸載的分區。
- 如果你仍然不能卸載分區，使用`--force`選項：

      # umount -f /mnt

  ， 或使用 `umount --lazy` 直接釋放掛載。這是，請立即重啟系統以避免不一致的狀態導致衝突。

## 在 chroot 中運行圖形程序

如果系統上運行了X，可以在 chroot 環境啟動圖形應用。

為了chroot環境能連接到你的X伺服器，在X伺服器中打開一個終端(例如，在用戶當前登錄的桌面中)，然後運行如下命令給任何人連接到用戶X伺服器的權限(另見 Xhost)：

    $ 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

### Unshare

Unshare 是 util-linux包 的一部分，可以用來創建新的內核命名空間。它使用常規的 chroot 命令運行，例如：

    $ unshare --map-root-user chroot ~/namespace /bin/sh

## 疑難解答

### arch-chroot: /location/of/new/root is not a mountpoint. This may have undesirable side effects.

執行 `arch-chroot /location/of/new/root` 命令後，出現以下警告：

    ==> WARNING: /location/of/new/root is not a mountpoint. This may have undesirable side effects.

見 arch-chroot(8) 中的解釋和使用綁定掛載讓 chroot 目錄變成掛載點的例子。

## 另見

- 基礎 Chroot

分類：​

- 系統恢復

chroot
新增話題