Difference between revisions of "Chroot (简体中文)"

From ArchWiki
Jump to navigation Jump to search
m (将"$ xhost +local"改为"$ xhost +local:")
 
(23 intermediate revisions by 9 users not shown)
Line 1: Line 1:
 
[[Category:System recovery (简体中文)]]
 
[[Category:System recovery (简体中文)]]
[[en:Change Root]]
+
[[en:Chroot]]
{{TranslationStatus (简体中文)|Change_Root|2012-11-06|}}
+
[[es:Chroot]]
 +
[[fa:تغییر ریشه]]
 +
[[fr:Chroot]]
 +
[[ja:Chroot]]
 +
[[pt:Chroot]]
 +
[[ru:Chroot]]
 +
{{TranslationStatus (简体中文)|Change_Root|2017-12-12|485038}}
 +
[[Wikipedia:Chroot|Chroot]] 就是变更当前进程及其子进程的可见根路径。变更后,程序无法访问可见根目录外文件和命令。这个目录叫作 ''chroot jail''。
  
 +
== 原因 ==
  
[[Wikipedia:Chroot|Chroot]] is the process of changing of the apparent disk root directory (and the current running process and its children) to another root directory. When you change root to another directory you cannot access files and commands outside that directory. This directory is called a ''chroot jail''. Changing root is commonly done for system maintenance, such as reinstalling the bootloader or resetting a forgotten password.
+
切换根目录通常为了系统维护,例如重装引导程序或者重置遗忘的密码。
  
== Requirements ==
+
* 重新安装 [[bootloader]].
 +
* 重建 [[mkinitcpio|initramfs 镜像]].
 +
* 更新或 [[downgrading packages|降级软件包]].
 +
* 重置 [[Password recovery|忘记的密码]].
 +
* 在干净的 chroot 中构建软件包:[[DeveloperWiki:Building in a clean chroot]].
  
* You'll need to boot from another working Linux environment (e.g. from a LiveCD or USB flash media, or from another installed Linux distribution).
+
参阅 [[Wikipedia:Chroot#Limitations]].
  
* Root privileges are required in order to chroot.
+
== 必要条件 ==
  
* Be sure that the architecture of the Linux environment you have booted into matches the architecture of the root directory you wish to enter (i.e. i686, x86_64). You can find the architecture of your current environment with:
+
* root 权限
 +
* 另一个 linux 环境,例如 liveCD、USB 闪存介质或者一个已经安装的另一个 linux 发行版。
 +
* 匹配的架构,chroot 前后的环境架构要一致(例如,都是 i686 x86_64)。可以用以下命令查看当前环境的架构 {{bc|uname -m}}
 +
* 提前加载 chroot 环境需要的内核模块
 +
* 如果需要 swap, chroot 前先启用 swap ({{ic|swapon /dev/sdxY}})
 +
* 如果需要网络,chroot 之前先建立好网络连接。
  
: {{bc|# uname -m}}
+
== 用法 ==
  
* If you need any kernel modules loaded in the chroot environment, load them before chrooting. It may also be useful to initialize your swap ({{ic|swapon /dev/sdxY}}) and to establish an internet connection before chrooting.
+
{{Note|
 +
*有些[[systemd]] 工具无法在 chroot 中运行,例如 ''localectl'' 和 ''timedatectl'',因为这些程序需要可用的 [[dbus]] 连接. [https://github.com/systemd/systemd/issues/798#issuecomment-126568596]
 +
*新的 root ({{ic|/}}) 所在的文件系统必须是可用访问的状态(提前解密、挂载).}}
  
== Mount the partitions ==
+
有两种使用 chroot 的方式:
  
The root partition of the Linux system that you're trying to chroot into needs to be mounted. To find out the device name assigned by the kernel, run:
+
=== 使用 arch-chroot ===
  
# lsblk /dev/sda
+
{{ic|arch-chroot}} bash 脚本是软件包 {{Pkg|arch-install-scripts}} 的一部分,在运行 {{ic|/usr/bin/chroot}} 前,这个脚本会挂载 {{ic|/proc}} api 文件系统,建立可用的 {{ic|/etc/resolv.conf}}。
  
Then create a directory where you would like to mount this partition and mount it:
+
进入 chroot
  
  # mkdir /mnt/arch
+
  # arch-chroot ''/location/of/new/root''
# mount /dev/sda3 /mnt/arch
 
  
Next, if you have separate partitions for other parts of your system (e.g. {{ic|/boot}}, {{ic|/home}}, {{ic|/var}}, etc), you should mount them, as well:
+
例如在 [[installation guide|安装指南]] 中,chroot 到 {{ic|/mnt}}:
  
  # mount /dev/sda1 /mnt/arch/boot/
+
  # arch-chroot /mnt
# mount /dev/sdb5 /mnt/arch/home/
 
# mount ...
 
  
While it's possible to mount filesystems after you've chrooted, it is more convenient to do so beforehand. The reasoning for this is that you'll have to unmount the temporary filesystems after you exit the chroot, so this lets you umount all the filesystems with a single command. This also allows for a safer shutdown. Because the external Linux environment knows all mounted partitions, it can safely unmount them during shutdown.
+
退出 chroot:
  
== Change root ==
+
# exit
 +
 
 +
==== 运行一个命令并退出 ====
 +
 
 +
用下面命令在 chroot 中运行一个命令并退出:
 +
 
 +
# arch-chroot ''/location/of/new/root'' ''mycommand''
 +
 
 +
例如要在 {{ic|/mnt/arch}} 中运行 {{ic|mkinitcpio -p linux}} 并退出:
 +
 
 +
# arch-chroot /mnt/arch mkinitcpio -p linux
 +
 
 +
=== 使用 chroot ===
  
Mount the temporary filesystems:
+
{{警告|使用 {{ic|--rbind}} 选项时,将无法卸载某些 {{ic|dev/}} 和 {{ic|sys/}} 的子目录,用 {{ic|umount -l}} 卸载将会破坏会话并需要重启,所以请尽可能使用 {{ic|-o bind}}。}}
  
{{Note|Using a newer (2012) Arch release, the following {{ic|mount}} commands can be replaced with {{ic|arch-chroot /mnt/arch}}, if the root partition was mounted in that location. Of course, you may still type these, if you want, or if you only have some other "live" Linux distribution.}}
+
作为 root 挂载 api 文件系统:
  
  # cd /mnt/arch
+
  # cd ''/location/of/new/root''
 
  # mount -t proc proc proc/
 
  # mount -t proc proc proc/
  # mount -t sysfs sys sys/
+
  # mount --rbind /sys sys/
  # mount -o bind /dev dev/
+
  # mount --rbind /dev dev/
  # mount -t devpts pts dev/pts/
+
 
 +
可选挂载:
 +
 
 +
  # mount --rbind /run run/
  
If you established an internet connection and want to use it in the chroot environment, you may have to copy over your DNS servers so that you will be connected to the network:
+
如果已经建立了一个网络连接并且想在 chroot 环境中继续使用,将 DNS 服务器配置复制到新环境:
  
 
  # cp -L /etc/resolv.conf etc/resolv.conf
 
  # cp -L /etc/resolv.conf etc/resolv.conf
  
Now chroot into your installed system and define your shell:
+
chroot 到新环境中并启用指定 shell
  
  # chroot . /bin/bash
+
  # chroot /mnt/arch /usr/bin/bash
  
{{Note|If you see the error {{ic|chroot: cannot run command '/bin/bash': Exec format error}}, it is likely that the two architectures do not match.}}
+
{{Note|
 +
* 如果遇到错误 {{ic|chroot: cannot run command '/bin/bash': Exec format error}},很可能两个环境架构不匹配。
 +
* 如果遇到错误 {{ic|chroot: '/usr/bin/bash': permission denied}},用执行权限重新挂载: {{ic|mount -o remount,exec /mnt/arch}}。
 +
}}
  
Optionally, to source your Bash configuration ({{ic|~/.bashrc}} and {{ic|/etc/bash.bashrc}}), run:
+
(可选)加载 Bash 配置文件({{ic|~/.bashrc}} {{ic|/etc/bash.bashrc}}),运行:
  
 
  # source ~/.bashrc
 
  # source ~/.bashrc
 
  # source /etc/profile
 
  # source /etc/profile
  
Optionally, create a unique prompt to be able to differentiate your chroot environment:
+
或创建一个独特的提示符来区别你的chroot环境:
  
 
  # export PS1="(chroot) $PS1"
 
  # export PS1="(chroot) $PS1"
  
== Run graphical chrooted applications ==
+
退出 chroot 环境:
 +
 
 +
# exit
  
If you have [[X]] running on your system, you can start graphical applications from the chroot environment.
+
然后卸载临时文件系统:
  
To allow the connection to your X server, you have to run the following from a terminal:
+
# cd /
 +
# umount --recursive ''/location/of/new/root''
  
# xhost +
+
如果出现 {{ic|/mnt}}(或其它任何分区) is busy, 这可能意味着:
  
Then, to direct the applications to your X server, run:
+
* chroot环境中残留了一个运行的程序或者还有分区没有被卸载,退出程序并用  {{ic|mount | grep /mnt/arch}} 查找未卸载的分区。
 +
* 如果你仍然不能卸载分区,使用{{ic|--force}}选项:{{bc|# umount -f /mnt}}, 或使用 {{ic|umount --lazy}} 直接释放挂载。这是,请立即重启系统以避免不一致的状态导致冲突。
  
# export DISPLAY=:0.0
+
== 在 chroot 中运行图形程序 ==
  
== Perform system maintenance ==
+
如果系统上运行了[[X]],可以在 chroot 环境启动图形应用。
  
At this point you can perform whatever system maintenance you require inside the chroot environment. A few common examples are:
+
为了chroot环境能连接到你的X服务器,在X服务器中打开一个终端(例如,在用户当前登录的桌面中),然后运行如下命令给任何人连接到用户X服务器的权限:
  
* Reinstall the bootloader.
+
$ xhost +local:
* Rebuild your [[mkinitcpio|initramfs]] image.
 
* Upgrade or [[Downgrading_Packages|downgrade]] packages.
 
* Reset a [[Password_Recovery|forgotten password]].
 
  
== Exit the chroot environment ==
+
然后,从chroot环境中将应用指向你的X服务器,将chroot中的DISPLAY环境变量设定成和拥有X服务器的用户DISPLAY变量相匹配。例如,运行:
  
When you're finished with system maintenance, exit the chroot:
+
$ echo $DISPLAY
  
# exit
+
作为拥有X服务器的用户查看DISPLAY的值。如果是“:0”(例如是),然后在chroot环境中运行
  
Then unmount the temporary filesystems and any mounted devices:
+
# export DISPLAY=:0
  
# umount {proc,sys,dev,boot,[...],}
+
现在就可以从chroot命令行启动图形界面应用
  
Finally, attempt to unmount your root partition:
+
== 不使用 root 权限 ==
  
# cd ..
+
Chroot 需要 root 权限,有时用户并没有这个权限,下面工具可用实现类似的功能:
# umount arch/
 
  
{{Note|If you get an error saying that {{ic|/mnt}} (or any other partition) is busy, this can mean one of two things:
+
=== PRoot ===
  
* A program was left running inside of the chroot.
+
[[PRoot]] 可用在没有 root 权限的情况下,用 {{ic|mount --bind}} 设置可见根目录,这样可用为不同的 CPU 架构编译程序。这个程序的缺点是文件属于主机系统。可用用 {{ic|--root-id}} 选项解决一部分问题。
  
* Or, more frequently, a sub-mount still exists (e.g. {{ic|/mnt/arch/boot}} within {{ic|/mnt/arch}}). Check with {{ic|lsblk}} to see if there are any mountpoints left:
+
=== Fakechroot ===
  
: {{bc|lsblk /dev/sda}}
+
{{Pkg|fakechroot}} 是一个拦截 chroot 调用并伪造结果的程序。用 {{Pkg|fakeroot}} 可用为普通用户伪造一个 chroot 环境:
  
: If you are still unable to unmount a partition, use the {{ic|--force}} option:
+
# fakechroot fakeroot chroot ~/my-chroot bash
  
: {{bc|# umount -f /mnt}}}}
+
== 参阅 ==
  
After this, you will be able to safely reboot.
+
* [https://help.ubuntu.com/community/BasicChroot Chroot 基础]

Latest revision as of 09:20, 6 April 2019

翻译状态: 本文是英文页面 Change_Root翻译,最后翻译时间:2017-12-12,点击这里可以查看翻译后英文页面的改动。

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

原因

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

参阅 Wikipedia:Chroot#Limitations.

必要条件

  • root 权限
  • 另一个 linux 环境,例如 liveCD、USB 闪存介质或者一个已经安装的另一个 linux 发行版。
  • 匹配的架构,chroot 前后的环境架构要一致(例如,都是 i686 或 x86_64)。可以用以下命令查看当前环境的架构
    uname -m
  • 提前加载 chroot 环境需要的内核模块
  • 如果需要 swap, chroot 前先启用 swap (swapon /dev/sdxY
  • 如果需要网络,chroot 之前先建立好网络连接。

用法

Note:
  • 有些systemd 工具无法在 chroot 中运行,例如 localectltimedatectl,因为这些程序需要可用的 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
Note:
  • 如果遇到错误 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

参阅