之前在某处看到了这么一份用于进入 Chroot 环境的 Bash 脚本,感觉不错就收藏了。先贴一下原始脚本:
1#!/bin/bash
2
3CHROOT_DIR=$(dirname $(readlink -f $0))
4
5USAGE="
6Usage: sh $0 [option]
7
8Warning: This script cannot be used in compile_env
9Options:
10 init init compile_env and mount the required directories
11 no option default to init
12 umount clean up compile_env
13 --help Display help information.
14Example:
15 enter compile_env: sh $0
16 sh $0 init
17 umount compile_env: sh $0 umount
18"
19
20function fn_umount()
21{
22 i=0
23 while tac /proc/mounts | grep "${CHROOT_DIR}" &> /dev/null
24 do
25 while read line;
26 do
27 if echo $line | grep ${CHROOT_DIR} &> /dev/null; then
28 dir=$(echo $line | awk '{print $2}')
29 umount --lazy $dir
30 fi
31 done < /proc/mounts
32 ((i++))
33 if [ $i -ge 8 ]; then
34 break
35 fi
36 done
37}
38
39function fn_init()
40{
41 tac /proc/mounts | grep "${CHROOT_DIR}/dev" &> /dev/null
42 if [ $? -ne 0 ]; then
43 mount --bind /dev ${CHROOT_DIR}/dev/
44 fi
45 tac /proc/mounts | grep "${CHROOT_DIR}/sys" &> /dev/null
46 if [ $? -ne 0 ]; then
47 mount --bind /sys ${CHROOT_DIR}/sys
48 fi
49 tac /proc/mounts | grep "${CHROOT_DIR}/proc" &> /dev/null
50 if [ $? -ne 0 ]; then
51 mount --bind /proc ${CHROOT_DIR}/proc
52 fi
53 tac /proc/mounts | grep "${CHROOT_DIR}/dev/pts" &> /dev/null
54 if [ $? -ne 0 ]; then
55 mount -n -tdevpts -omode=0620,gid=5 none ${CHROOT_DIR}/dev/pts
56 fi
57
58 chroot ${CHROOT_DIR} /bin/bash --login
59}
60
61#--------------------main-------------------#
62if [ ${CHROOT_DIR} == "/" ]; then
63 echo -e "\033[31m\033[01m[ Warning: This script cannot be used in compile_env ]\033[0m"
64 printf "%s\\n" "$USAGE"
65 exit 1
66fi
67
68if [ $# -gt 1 ]; then
69 echo -e "\033[31m\033[01m[ missing params, please check it! ]\033[0m"
70 printf "%s\\n" "$USAGE"
71 exit 2
72fi
73
74if [ $# -eq 0 ] || [ $1 == "init" ]; then
75 fn_init
76 trap "sh ${CHROOT_DIR}/chroot.sh umount" EXIT
77 exit 0
78elif [ $1 == "umount" ]; then
79 fn_umount
80 exit 0
81else
82 printf "%s\\n" "$USAGE"
83 exit 3
84fi
下面就这个脚本中的一些内容做讲解。
-
umount
的--lazy
选项根据
man umount(8)
所述:1-l, --lazy 2 Lazy unmount. Detach the filesystem from the file hierarchy 3 now, and clean up all references to this filesystem as soon 4 as it is not busy anymore.
就是在对文件系统的引用还没有被全部解除的情况下,把文件系统移出文件目录树。这个 man 还给出了它的使用场景:避免系统的重启和关闭过程阻塞于网络文件系统(NFS)或一些本地文件系统无法被卸载。
实际上使用
umount -l
还是有可能带来风险的,因为你不知道文件向设备的回写到底什么时候会完成,也没有东西可以指示你。比如你用umount -l
卸载了一块硬盘,命令执行完成后你可能就拔硬盘了,但这个时候硬盘上的文件可能还没有 sync 完(其实你也没法知道到底 sync 完了没有),导致硬盘文件损坏。但是在此处问题应该不大,因为挂载的都是基于内存的文件系统或伪文件系统,不存在磁盘和内存不同步的问题。
-
tac
:就是将cat
输出的顺序取反。 -
trap
的含义这是一个 Bash 的内置命令(builtin),指定 Bash 在收到某个信号的时候要执行的函数。除信号外,还可以额外指定
EXIT
(等同于 0)、DEBUG
和ERR
等情况,其中EXIT
是指 Bash 退出的时刻,即指定 Bash 退出时要执行的命令。更多细节可查 Bash Manual 4.1 节 和 Bash Guide for Beginners 12.2 节 。
当然,这份代码还存在可改进之处。使用时根据实际情况调整即可。