文章目录
原文章地址http://www.crazydeveloper007.com/raspi-custom-img/
引言:概括的说本案中先使用dd命令对TF设备进行.img镜像的制作,而后使用GitHub上面开源的PiShrink.sh脚本对制作好的.img镜像文件进行"压缩"处理(实际是调整了镜像分区的大小)。
1 准备工作
(1)要制作为镜像的TF卡,TF卡读卡器;
(2)一台Linux操作系统的电脑;
(3)PiShrink.sh脚本(GitHub开源项目) ,见本文附录
PS:笔者TF卡中为Ubuntu Server 20.04.3 LTS 系统,并且部署了好多服务,如果需要建集群,一个一个的树莓去装环境,部署服务,我会崩溃的……
2 使用dd命令为TF卡制作做镜像
2.1 查找设备文件(Linux系统一切皆文件)
终端下输入lsblk
查找TF设备文件,笔者的是sdb,即一张16GB的TF卡
2.2 使用dd命令将sdb设备(TF卡)制作成镜像文件
PS:本步骤前请确保磁盘空间足够,确保能够存放16GB-TF卡镜像文件
# 以下命令将sdb压缩到/home目录的rpi.img文件中
dd if=/dev/sdb of=/home/rpi.img bs=8M
PS:制作.img需要点时间,请耐心等待,笔者的16GB-TF卡这一步骤制作镜像花费了3分钟左右(终端回显数据中显示为175.129s),在制作过程中终端无任何回显,要稍加等待,笔者使用的是品胜USB3.0的读卡器,电脑上USB口同为3.0接口。
3 使用PiShrink(Shell脚本)“压缩”制作的.img镜像
这里可以理解为dd命令是将TF卡,整盘克隆了下来(包括分区中未用到的空间),我们使用PiShrink将.img文件进行瘦身处理
3.1 使用vim工具新建PiShrink.sh脚本文件
PS:这一步可将从GitHub上面down下来的PiShrink.sh文件拷贝至/home目录下
# PiShrink.sh文件内容见附录,vim的使用方式这里不做说明,用vim工具新建PiShrink.sh文件,并将附录中的脚本源码Copy至/home/PiShrink.sh文件中保存
vim /home/PiShrink.sh
3.2 执行PiShrink.sh
# 进入/home目录
cd /home
# 修改PiShrink.sh文件权限,使之变为可执行文件
sudo chmod 755 PiShrink.sh
# 执行脚本进行压缩,其中rpi.img为dd命令生成的img文件,my-raspi.img为用Shell脚本生成的新.img文件
sudo ./PiShrink.sh -s rpi.img my-raspi.img
PS:该步骤需要稍加等待,如图所示15G的源.img文件(dd命令制作)被该脚本“压缩”为了3.1G,我们将3.1G的镜像文件拷贝出来,使用Win32DiskImager工具便可向新的TF卡中烧录制作的镜像。烧录完后不要忘记给分区进行扩容(原TF卡中未使用到的空间被PiShrink"压缩"掉了)
4 附录:
4.1 PiShrink脚本源码
PS:这里由衷感谢PiShrink脚本作者,向您学习开源精神!制作树莓派镜像用这个方法,简直是太方便了!
PiShrink项目地址:https://github.com/Drewsif/PiShrink
PiShrink.sh(Shell脚本)内容如下:
#!/bin/bash
version="v0.1.2"
CURRENT_DIR="$(pwd)"
SCRIPTNAME="${0##*/}"
MYNAME="${SCRIPTNAME%.*}"
LOGFILE="${CURRENT_DIR}/${SCRIPTNAME%.*}.log"
REQUIRED_TOOLS="parted losetup tune2fs md5sum e2fsck resize2fs"
ZIPTOOLS=("gzip xz")
declare -A ZIP_PARALLEL_TOOL=( [gzip]="pigz" [xz]="xz" ) # parallel zip tool to use in parallel mode
declare -A ZIP_PARALLEL_OPTIONS=( [gzip]="-f9" [xz]="-T0" ) # options for zip tools in parallel mode
declare -A ZIPEXTENSIONS=( [gzip]="gz" [xz]="xz" ) # extensions of zipped files
function info() {
echo "$SCRIPTNAME: $1 ..."
}
function error() {
echo -n "$SCRIPTNAME: ERROR occured in line $1: "
shift
echo "$@"
}
function cleanup() {
if losetup "$loopback" &>/dev/null; then
losetup -d "$loopback"
fi
if [ "$debug" = true ]; then
local old_owner=$(stat -c %u:%g "$src")
chown "$old_owner" "$LOGFILE"
fi
}
function logVariables() {
if [ "$debug" = true ]; then
echo "Line $1" >> "$LOGFILE"
shift
local v var
for var in "$@"; do
eval "v=\$$var"
echo "$var: $v" >> "$LOGFILE"
done
fi
}
function checkFilesystem() {
info "Checking filesystem"
e2fsck -pf "$loopback"
(( $? < 4 )) && return
info "Filesystem error detected!"
info "Trying to recover corrupted filesystem"
e2fsck -y "$loopback"
(( $? < 4 )) && return
if [[ $repair == true ]]; then
info "Trying to recover corrupted filesystem - Phase 2"
e2fsck -fy -b 32768 "$loopback"
((