我需要创建多个运行 Ubuntu 的 USB 闪存驱动器。这些闪存驱动器应该:
- 包含定制预装软件
- 坚持下去:即使重新启动后,程序和应保留新文件
我怎么能够自动化这个过程可以避免手动步骤(除了插入驱动器)吗?
答案1
创建一个执行所有必要步骤的脚本并在安装后执行它。
例如:
#!/bin/bash
set -e
apt update
apt install -y \
vlc \
curl \
git \
filezilla \
... others to be installed
apt purge -y \
thunderbird \
... others to be uninstalled
gsettings set org.gnome.shell.extensions.desktop-icons show-trash false
apt upgrade -y
apt autoremove -y
您甚至可以将脚本放在网上某个地方并通过以下方式运行它
wget -qO- https://example.com/script.sh | sudo bash
答案2
根据@user535733 的建议,我最终做了以下事情:
1. 在闪存驱动器上安装 Ubuntu/Lubuntu
这些说明大致如下这个答案。
(准备)
- 创建实时 USB 或 DVD。
- 关闭计算机并拔掉电源插头。
- 拔下计算机上的所有硬盘。
- 重新插入计算机。
- 在 UEFI 设置中禁用安全启动和快速启动(具体步骤因供应商而异)
(运行安装程序)
- 插入 Live USB 或 Live DVD。
- 启动计算机,USB/DVD 应该启动。
- 选择安装 Ubuntu。
- 插入新的目标驱动器来安装 Ubuntu。
- 按照说明进行操作。
- 不要安装“第三方软件”,因为它可能无法在其他机器上运行。
- 在“安装类型”中选择“其他”。
- 选择“继续”。
- 选择目标驱动器(在我的情况下是 /dev/sdb)
- 选择“新建分区表”并“继续”。
(EFI 分区)
- 单击“可用空间”和“+”。
- “大小”:100 MB
- 选择“主要”
- “位置”:“此空间的开始”
- “用作”:“EFI 系统分区”
- 选择“确定”
(/ 分割)
- 单击“可用空间”,然后单击“+”。
- “大小”:7800 MB(或其他数字)
- 选择“主要”
- “位置”:“此空间的开始”
- “用作”:“Ext4”
- 挂载点:“/”
- 选择“确定”
(重要的)
确保“用于引导加载程序安装的设备”指向闪存驱动器的根目录(在我的情况下为 /dev/sdb)。
单击“立即安装”和“继续”。
- 按照说明进行操作。
- 等到安装完成。
(包起来)
- 关闭计算机并插入硬盘。
2. 保存生成的闪存驱动器
接下来,将生成的图像保存到您的机器。我编写了一个脚本来处理此步骤。
#!/bin/bash
#
# Saves flash drive partitions to disk
#
# Example Usage:
# ./copy.sh /dev/sde ./images
# enable bash strict mode
# http://redsymbol.net/articles/unofficial-bash-strict-mode/
set -euo pipefail
IFS=$'\n\t'
##########
# INPUTS #
##########
# Checking inputs
if [ $# -ne 2 ]; then
echo "USAGE: ./copy.sh DEVICE OUTPUTDIR"
echo "Available devices:"
sudo lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINT,LABEL,UUID,MODEL
exit
fi
# parse inputs
DEVICE=$1
OUTPUTDIR=$2
EFIFILE=$OUTPUTDIR/ubuntu-efi.img
ROOTFILE=$OUTPUTDIR/ubuntu-root.img
PARTITIONFILE=$OUTPUTDIR/partitions.txt
# Display helpful information
echo "Saving device $DEVICE to $OUTPUTDIR:"
sudo lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINT,LABEL,UUID,MODEL $DEVICE
# Confirm
read -r -p "Continue? [y/N] " response
if [[ "$response" =~ ^([yY][eE][sS]|[yY])$ ]]; then
echo "Start copying (this could take a long time)..."
else
echo "Aborting" >&2
exit
fi
mkdir -p "$OUTPUTDIR"
########
# SAVE #
########
# record sizes
sudo fdisk -l | grep ${DEVICE} | sed "s#${DEVICE}#/dev/sdX#g" > $PARTITIONFILE
# dd: copy and convert
# if: source disk
# bs: sector size value from fdisk output
# count: last "end" sector from fdisk output incremented by one
# conv=sync,noerror: sync I/O and don't stop in case of errors on the source disk
sudo dd if=${DEVICE}1 conv=sync,noerror of=$EFIFILE
sudo dd if=${DEVICE}2 conv=sync,noerror of=$ROOTFILE
3. 安装到新驱动器
最后,将保存的映像安装到新的闪存驱动器。同样,我编写了一个脚本来处理此步骤。
#!/bin/bash
#
# Installs Ubuntu/Lubuntu to flash drive
#
# Example Usage:
# ./copy.sh /dev/sde ./images
###########
# HELPERS #
###########
# enable bash strict mode
# http://redsymbol.net/articles/unofficial-bash-strict-mode/
set -euo pipefail
IFS=$'\n\t'
# directory containing this script
BASEDIR="$( dirname "$0")"
# run commands at the end of the script (even on errors)
EXIT=""
function addExit {
# call the argument before ending the script
EXIT="$@ ; $EXIT"
trap "echo 'Final tasks before exit...' ; $EXIT" EXIT HUP TERM INT QUIT
}
##########
# INPUTS #
##########
# Checking inputs
if [ $# -ne 2 ]; then
echo "USAGE: ./copy.sh DEVICE SOURCEDIR"
echo "Available devices:"
sudo lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINT,LABEL,UUID,MODEL
exit
fi
# parse inputs
DEVICE="$1"
SOURCEDIR="$2"
MNT=/mnt
# Display helpful information
echo "Installing to device $DEVICE:"
sudo lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINT,LABEL,UUID,MODEL $DEVICE
# Confirm
read -r -p "Continue? [y/N] " response
if [[ "$response" =~ ^([yY][eE][sS]|[yY])$ ]]; then
echo "Preparing partitions..."
else
echo "Aborting" >&2
exit
fi
# record sizes
PARTITIONFILE="$SOURCEDIR/partitions.txt"
EFISTART=$( cat "$PARTITIONFILE" | grep /dev/sdX1 | awk -F" " '{ print $2 }')
EFIEND=$( cat "$PARTITIONFILE" | grep /dev/sdX1 | awk -F" " '{ print $3 }')
ROOTSTART=$(cat "$PARTITIONFILE" | grep /dev/sdX2 | awk -F" " '{ print $2 }')
ROOTEND=$( cat "$PARTITIONFILE" | grep /dev/sdX2 | awk -F" " '{ print $3 }')
#######################
# COPY TO FLASH DRIVE #
#######################
# umount all paritions of this device
echo "Unmounting all partitions of $DEVICE..."
sudo umount $DEVICE?* || true
# create partition table
sudo wipefs --all $DEVICE
sudo parted $DEVICE mklabel gpt
# efi partition
sudo parted $DEVICE mkpart primary fat32 ${EFISTART}s ${EFIEND}s
sudo parted $DEVICE set 1 boot on
sudo parted $DEVICE set 1 esp on
echo "Start copying efi..."
EFIFILE="$SOURCEDIR/ubuntu-efi.img"
sudo dd if="$EFIFILE" of=${DEVICE}1
# root partition
sudo parted $DEVICE mkpart primary ext4 ${ROOTSTART}s ${ROOTEND}s
# sudo parted $DEVICE name 2 UbuntuUSB
echo "Start copying root (this could take a long time)..."
ROOTFILE="$SOURCEDIR/ubuntu-root.img"
sudo dd if="$ROOTFILE" of=${DEVICE}2
##################
# PREPARE CHROOT #
##################
# prepare running command in root directory of new installation
sudo mount ${DEVICE}2 $MNT
addExit "sudo umount $MNT"
sudo mount ${DEVICE}1 $MNT/boot/efi
addExit "sudo umount $MNT/boot/efi"
for i in /dev /dev/pts /proc /sys; do
sudo mount -B $i ${MNT}$i
addExit "sudo umount ${MNT}$i"
done
sudo cp /etc/resolv.conf $MNT/etc/
modprobe efivars
########
# GRUB #
########
# update grub
sudo chroot $MNT grub-install -d /usr/lib/grub/x86_64-efi --efi-directory=/boot/efi/ --removable ${DEVICE}
#############
# CUSTOMIZE #
#############
# prepare scripts
sudo cp -r "${BASEDIR}/customize" "$MNT/opt/customize"
# install software
sudo chroot $MNT "/opt/customize/software.sh"
此脚本还会安装其他自定义软件,使用以下脚本./customize/software.sh
#!/bin/bash
# enable bash strict mode
# http://redsymbol.net/articles/unofficial-bash-strict-mode/
set -euo pipefail
IFS=$'\n\t'
###########
# PREPARE #
###########
# avoid locale issues and in order to import GPG keys
export HOME=/root
export LC_ALL=C
#######
# APT #
#######
apt-get update -y
apt-get clean
apt-get -y autoremove --purge
####################
# INSTALL SOFTWARE #
####################
# -y: auto-confirm
# -qq: quiet installation
apt-get install -y -qq \
htop \
gparted \
build-essential