chroot
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 之前先建立好網絡連接。
用法[編輯 | 編輯原始碼]
有兩種使用 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
。
(可選)加載 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 是 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 目錄變成掛載點的例子。