備份腳本:bash
#!/bin/bash # This script is used for backup raspberry pi image. # The default path is /dev/sdb1 and /dev/sdb2. # Don't connect PC two discks in the same time. #################################### #set -e #################################### # usage for script #################################### function usage { echo "usage: -s :start backup image" echo " -i [filename] :specify the exis image file" } #################################### # create image #################################### function createImage { echo "1.Creating Image ..." BOOT_DEV='/dev/sdb1' ROOT_DEV='/dev/sdb2' TIME=`date "+%Y%m%d%H%M%S"` BOOT_SIZE=`sudo df -P | grep $BOOT_DEV | awk '{print $3}'` ROOT_SIZE=`sudo df -P | grep $ROOT_DEV | awk '{print $3}'` echo "[createImage] BOOT_DEV="$BOOT_DEV echo "[createImage] ROOT_DEV="$ROOT_DEV echo "[createImage] TIME="$TIME echo "[createImage] BOOT_SIZE="$BOOT_SIZE echo "[createImage] ROOT_SIZE="$ROOT_SIZE if [ $# -eq 0 ];then FILE=backup_$TIME.img SIZE=`echo $BOOT_SIZE $ROOT_SIZE | awk '{print int(($1+$2)*1.1/1024)}'` echo "[createImage] FILE="$FILE echo "[createImage] SIZE="$SIZE dd if=/dev/zero of=$FILE bs=1M count=$SIZE echo "Create done." else FILE=$1 echo "skip create Image." fi echo } #################################### # mount source file #################################### function mountSrcFile { echo "2.Mount source boot and root" mkdir src_boot src_root MY_UID=$(whoami) sudo mount -t vfat -o uid=$MY_UID,gid=$MY_UID,umask=0000 $BOOT_DEV ./src_boot sudo mount -t ext4 $ROOT_DEV ./src_root echo "Mount done." echo } #################################### # Part Image #################################### function partImage { echo "3.Part Image ..." BOOT_START=`sudo fdisk -l /dev/sdb|grep $BOOT_DEV | awk '{print $2}'` BOOT_END=`sudo fdisk -l /dev/sdb|grep $BOOT_DEV | awk '{print $3}'` ROOT_START=`sudo fdisk -l /dev/sdb|grep $ROOT_DEV | awk '{print $2}'` parted $FILE --script -- mklabel msdos parted $FILE --script -- mkpart primary fat32 ${BOOT_START}s ${BOOT_END}s parted $FILE --script -- mkpart primary ext4 ${ROOT_START}s -1 parted $FILE --script -- quit echo "Part done." echo } #################################### # mount target file #################################### function mountTgtFile { DEBUG_MKFS="[mkfs]" echo "4.Mount target boot and root" LOOP_DEVICE=`sudo losetup -f --show $FILE` echo $DEBUG_MKFS"LOOP_DEVICE:"$LOOP_DEVICE PART_BOOT="/dev/mapper/"`sudo kpartx -va $LOOP_DEVICE | awk '/p1/{print $3}' | head -1` PART_ROOT="/dev/mapper/"`sudo kpartx -va $LOOP_DEVICE | awk '/p2/{print $3}' | head -1` echo $DEBUG_MKFS"PART_BOOT:"$PART_BOOT echo $DEBUG_MKFS"PART_ROOT:"$PART_ROOT echo $DEBUG_MKFS"wait loop device creating ..." sleep 5 sudo mkfs.vfat -n boot $PART_BOOT sudo mkfs.ext4 -L root $PART_ROOT mkdir tgt_boot tgt_root IMG_BOOT_OFF=$BOOT_START*512 IMG_ROOT_OFF=$ROOT_START*512 sudo mount -t vfat -o loop $PART_BOOT ./tgt_boot sudo mount -t ext4 -o loop $PART_ROOT ./tgt_root echo "Mount target file done." echo } #################################### # backup boot directory #################################### function backupBootDir { echo "5.backuping boot ..." sudo cp -rfp ./src_boot/* ./tgt_boot/ echo "backuping boot done." echo } #################################### # backup root directory #################################### function backupRootDir { echo "6.backuping root ... "$(date) cd src_root/ # sudo tar pcf ../rootbak.tar . echo "zip root directory done." echo cd ../tgt_root/ sudo tar pxf ../rootbak.tar echo "unzip root directory done." # rm -rf ../rootbak.tar cd .. echo "backuping done. "$(date) echo } #################################### # exit backup #################################### function exitingBackup { echo "7.exiting backup ..." sudo umount src_boot src_root tgt_boot tgt_root echo "wait for umount ..." sleep 2 rm -rf src_boot src_root tgt_boot tgt_root sudo kpartx -d $LOOP_DEVICE echo "wait for kpartx -d ..." sleep 2 sudo losetup -d $LOOP_DEVICE echo "exit backup done." echo } #################################### # start script #################################### if [ $# -eq 0 ];then usage exit 0 fi while getopts :si: opt do case "$opt" in s) echo "####################################" echo "# Now start backup Image #" echo "####################################" createImage mountSrcFile partImage mountTgtFile backupBootDir backupRootDir exitingBackup exit 0;; i) echo "####################################" echo "# Now start backup Image #" echo "####################################" if [ ! -f $OPTARG ];then echo "FILE '$OPTARG' is not a file" exit 1 fi createImage $OPTARG mountSrcFile partImage mountTgtFile backupBootDir backupRootDir exitingBackup exit 0;; *) echo "Not found option $opt" usage exit 0;; esac done echo "Maybe the script make a fault"
啓動修改,第一次啓動擴容sd卡:app
#!/bin/bash # This script is for resize the disk, when first run pi. # And add auto check Client file every time. ################################## ################################## #check if input image file name ################################## function checkInput { if [ ! -n "$1" ] ;then echo "you have not input a file!" exit fi FILE=$1 } ################################## #mount image boot part ################################## function mountImageBoot { echo "check image file ..." if [ ! -f $FILE ];then echo "$FILE is not exsited." exit fi BOOT_START=`sudo fdisk -l $FILE|grep "FAT32"|awk '{print $2}'` BOOT_START=$[ $BOOT_START * 512 ] echo "BOOT_START:"$BOOT_START sudo mkdir fix_boot echo "mount boot part" sudo mount -t vfat -o loop,offset=$BOOT_START $FILE fix_boot } ################################## #mount image root part ################################## function mountImageRoot { echo "check image file ..." if [ ! -f $FILE ];then echo "$FILE is not exsited." exit fi ROOT_START=`sudo fdisk -l $FILE|grep "Linux"|awk '{print $2}'` ROOT_START=$[ $ROOT_START * 512 ] echo "BOOT_START:"$BOOT_START sudo mkdir fix_root sudo chmod 777 fix_root echo "mount root part" sudo mount -t ext4 -o loop,offset=${ROOT_START} ${FILE} fix_root } ################################## #fix image start ################################## function fixImageStart { echo "fix image start ..." if [ ! -f $FILE ] then echo "$FILE is not exsited." exit fi BOOT_START=`sudo fdisk -l $FILE|grep "FAT32"|awk '{print $2}'` ROOT_START=`sudo fdisk -l $FILE|grep "Linux"|awk '{print $2}'` BOOT_START=$[ $BOOT_START * 512 ] ROOT_START=$[ $ROOT_START * 512 ] echo "BOOT_START:"$BOOT_START echo "ROOT_START:"$ROOT_START sudo mkdir fix_root fix_boot sudo chmod 777 fix_root sudo umount fix_boot fix_root echo "[fix image] mount image ..." sudo mount -t ext4 -o loop,offset=${ROOT_START} ${FILE} fix_root sudo mount -t vfat -o loop,offset=$BOOT_START $FILE fix_boot echo "fixImageStart done" echo } ################################## #fix PARTUUID in root/etc/fstab ################################## function fixPARTUUID { echo "fix PARTUUID in /etc/fstab" FSTAB_FILE="fix_root/etc/fstab" if [ ! -f $FSTAB_FILE ];then echo "${FSTAB_FILE} not exist" exit fi NEW_PARTUUID=`sudo fdisk -l $FILE|sed -n 6p|sed 's/0x/ /' |awk '{print $2}'` OLD_PARTUUID=`awk '/PARTUUID=[a-zA-Z 0-9]/&&/ext4/{print $1}' $FSTAB_FILE | sed 's/PARTUUID=//;s/-02//'` echo "NEW_PARTUUID:"$NEW_PARTUUID echo "OLD_PARTUUID:"$OLD_PARTUUID if [ -z $NEW_PARTUUID ] then echo "[ERROR]:NEW_PARTUUID is empty" sudo umount fix_root fix_boot exit fi if [ -z $OLD_PARTUUID ] then echo "OLD_PARTUUID is empty, deal with ..." sudo sed -i "s/PARTUUID=/PARTUUID=$NEW_PARTUUID/g" $FSTAB_FILE else sudo sed -i "s/$OLD_PARTUUID/$NEW_PARTUUID/g" $FSTAB_FILE echo "fix PARTUUID done." fi echo "fixPARTUUID done." echo } ################################## #add init_resize.sh in cmdline.txt ################################## function addInitResize { CMDLINE_FILE="./fix_boot/cmdline.txt" echo "add init_resize.sh in cmdline.txt" if [ "`grep "init_resize.sh" $CMDLINE_FILE`" ] then echo "Exist init_resize.sh" else echo "Not exist init_resize.sh" sudo sed -i "1 s/$/& init=\/usr\/lib\/raspi-config\/init_resize.sh/" $CMDLINE_FILE echo "add init_resize.sh done." fi echo "fix image done." echo } ################################## #add resize space script ################################## function addFreeSpace { ROOT_DIR=./fix_root RESIZE_DIR=./fix_root/usr/local/soonsolid RESIZE_FILE="resize2fs_once" #set directory exsit if [ ! -d $RESIZE_DIR ];then echo "[addFreeSpace] create soonsolid directory" sudo mkdir -p $RESIZE_DIR fi #add boot file in rc.local sudo sed -i '/^exit 0$/iexec \/usr\/local\/soonsolid\/resize2fs_once' $ROOT_DIR/etc/rc.local sudo touch $RESIZE_DIR"/"$RESIZE_FILE echo "[addFreeSpace] write resize file:" sudo cat <<EOF | sudo tee $RESIZE_DIR/$RESIZE_FILE #!/bin/sh ROOT_PART=\$( mount | sed -n 's|^/dev/\(.*\) on / .*|\1|p') resize2fs /dev/\$ROOT_PART #remove boot file in rc.local sed -i '/resize2fs_once/d' /etc/rc.local reboot EOF sudo chmod 777 $RESIZE_DIR/$RESIZE_FILE echo "[addFreeSpace] write resize done." echo "addFreeSapce done" echo } ################################## #add check file ################################## function addCheckClientExist { CHECK_FILE=./check_SliceImageClient CHECK_LOG_FILE=$RESIZE_DIR/checklog CHECK_DIR=$RESIZE_DIR SLICEIMAGECLIENT_FILE=./fix_root/home/pi/SliceImageClient_update BACKUP_NAME="SliceImageClient_backup" echo "add check client script ..." #copy check file to /usr/local/soonsolid if [ -d $CHECK_DIR ];then sudo mkdir -p $CHECK_DIR fi sudo chmod 755 $CHECK_FILE sudo cp $CHECK_FILE $CHECK_DIR #add auto run to rc.local grep "check_SliceImageClient" $ROOT_DIR/etc/rc.local if [ $? != "0" ];then sudo sed -i '/^exit 0$/iexec \/usr\/local\/soonsolid\/check_SliceImageClient &' $ROOT_DIR/etc/rc.local fi #copy SliceImageClient file to soonsolid for backup sudo cp $SLICEIMAGECLIENT_FILE $CHECK_DIR/$BACKUP_NAME #remove log file if [ -f $CHECK_LOG_FILE ];then sudo rm $CHECK_LOG_FILE fi echo "add script done." echo } ################################## #clean log file ################################## function cleanlogfile { echo "clean log file ..." LOGFILE_PATH=$ROOT_DIR/home/pi/SoonSolid LOGFILE_NAME=logFile #remove log file if [ -f $LOGFILE_PATH/$LOGFILE_NAME ];then sudo rm $LOGFILE_PATH/$LOGFILE_NAME fi echo "clean log file done." echo } ################################## #clean boot ... ################################## function cleanBoot { echo "clean boot ..." sudo umount fix_boot echo "wait for umounting boot ..." sleep 2 sudo rmdir fix_boot echo } ################################## #clean root ... ################################## function cleanRoot { echo "clean root ..." sudo umount fix_root echo "wait for umounting root ..." sleep 2 sudo rmdir fix_root echo } ################################## #clean fix ... ################################## function exitFix { echo "clean fix ..." sudo umount fix_root fix_boot echo "wait for umounting ..." sleep 5 sudo rmdir fix_root fix_boot echo "clean fix done." echo } checkInput $1 mountImageRoot fixPARTUUID addFreeSpace addCheckClientExist cleanlogfile cleanRoot
樹莓派中的rasp-config的鏡像擴容函數:ide
#!/bin/bash ROOT_PART=$(mount | sed -n 's|^/dev/\(.*\) on / .*|\1|p') PART_NUM=${ROOT_PART#mmcblk0p} if [ "$PART_NUM" = "$ROOT_PART" ]; then whiptail --msgbox "$ROOT_PART is not an SD card. Don't know how to expand" 20 60 2 return 0 fi # NOTE: the NOOBS partition layout confuses parted. For now, let's only # agree to work with a sufficiently simple partition layout if [ "$PART_NUM" -ne 2 ]; then whiptail --msgbox "Your partition layout is not currently supported by this tool. You are probably using NOOBS, in which case your root filesystem is already expanded anyway." 20 60 2 return 0 fi LAST_PART_NUM=$(parted /dev/mmcblk0 -ms unit s p | tail -n 1 | cut -f 1 -d:) if [ $LAST_PART_NUM -ne $PART_NUM ]; then whiptail --msgbox "$ROOT_PART is not the last partition. Don't know how to expand" 20 60 2 return 0 fi # Get the starting offset of the root partition PART_START=$(parted /dev/mmcblk0 -ms unit s p | grep "^${PART_NUM}" | cut -f 2 -d: | sed 's/[^0-9]//g') [ "$PART_START" ] || return 1 echo "PART_NUM:"$PART_NUM echo "PART_START:"$PART_START # Return value will likely be error for fdisk as it fails to reload the # partition table because the root fs is mounted fdisk /dev/mmcblk0 <<EOF p d $PART_NUM n p $PART_NUM $PART_START p w EOF ASK_TO_REBOOT=1 # now set up an init.d script cat <<EOF > /etc/init.d/resize2fs_once && #!/bin/sh ### BEGIN INIT INFO # Provides: resize2fs_once # Required-Start: # Required-Stop: # Default-Start: 3 # Default-Stop: # Short-Description: Resize the root filesystem to fill partition # Description: ### END INIT INFO . /lib/lsb/init-functions case "\$1" in start) log_daemon_msg "Starting resize2fs_once" && resize2fs /dev/$ROOT_PART && update-rc.d resize2fs_once remove && rm /etc/init.d/resize2fs_once && log_end_msg \$? ;; *) echo "Usage: \$0 start" >&2 exit 3 ;; esac EOF chmod +x /etc/init.d/resize2fs_once && update-rc.d resize2fs_once defaults && if [ "$INTERACTIVE" = True ]; then whiptail --msgbox "Root partition has been resized.\nThe filesystem will be enlarged upon the next reboot" 20 60 2 fi #remove boot file in rc.local sed -i '/resize2fs_once/d' /etc/rc.local reboot