Advertisement
chuggerguy

clonetodevice

Nov 7th, 2024 (edited)
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 7.83 KB | Software | 0 0
  1. #!/bin/bash
  2. # Caution, do not run unless you already have a backup you trust.
  3. # I run this on my machine and I trust it.
  4. # But you should not trust a new backup plan unless you've not only
  5. # used it to backup, but also to do a successful restore.
  6. # This works for me, but it might not work for you.
  7. # Use at your own risk, I'm only an amateur, I miss up sometimes.
  8. # That said, it seems to work for me.
  9. #
  10.  
  11. if [ "$(id -u)" != "0" ]; then
  12.   exec sudo "$0" "$@"
  13. fi
  14.  
  15. user="$SUDO_USER"
  16. hostname=$(hostname)
  17.  
  18. main () {
  19.     determinesource;
  20.     checksource;
  21.     gettarget;
  22.     checktarget;
  23.     askifformatdesired;
  24.     if [[ $formatRequested == "y" ]]; then
  25.         doformat;
  26.     else
  27.         echo "skipping format";
  28.     fi
  29.     doclone;
  30.     fixgrub;
  31. }
  32.  
  33. #*************************determinesource******************************
  34. determinesource () {
  35.      slashmountedonpartition=$(mount | grep " / " | awk '{print $1}')
  36.  
  37.     if [[ $slashmountedonpartition == *"nvme"* ]]; then
  38.         sourcedevice=${slashmountedonpartition::-2}
  39.      else
  40.         sourcedevice=${slashmountedonpartition::-1}
  41.     fi
  42. }
  43. #***********************end determinesource****************************
  44.  
  45. #***********************checksource****************************
  46. checksource () {
  47. numpartitions=$(lsblk -nlpo NAME,TYPE $sourcedevice | awk '$2=="part"{print $1}' | wc -l)
  48.  
  49. if [ $numpartitions != 2 ]; then
  50.     echo "Sorry, this script only works with 2 specific partitions"
  51.     echo  "Partition #1 must be exactly \"EFI System\""
  52.     echo "Partition #2 must be exactly \"Linux filesystem\""
  53.     exit 1
  54. fi
  55.  
  56. if [[ $sourcedevice == *"nvme"* ]]; then
  57.     efipartition="$sourcedevice"p1
  58.     mainpartition="$sourcedevice"p2
  59. else
  60.     efipartition="$sourcedevice"1
  61.     mainpartition="$sourcedevice"2
  62. fi
  63.  
  64. efishort=$(echo $efipartition | awk -F'/' '{print $3}')
  65. mainshort=$(echo $mainpartition | awk -F'/' '{print $3}')
  66.  
  67.  
  68. #echo "efishort is: $efishort"
  69.  
  70. part1type=$(lsblk -o name,parttypename | grep $efishort | awk -F "$efishort" '{print $2}' | sed 's/^[[:space:]]*//')
  71.  
  72. part2type=$(lsblk -o name,parttypename | grep $mainshort | awk -F "$mainshort" '{print $2}' | sed 's/^[[:space:]]*//')
  73.  
  74. if [[ $part1type != "EFI System"  || $part2type != "Linux filesystem" ]]; then
  75.     echo "Sorry, partitions are wrong type"
  76.     echo "Partition #1 must be exactly \"EFI System\""
  77.     echo "Partition #2 must be exactly \"Linux filesystem\""
  78.     exit 2
  79. fi
  80.  
  81. }
  82. #***********************end checksource****************************
  83.  
  84. #*********************gettarget******************************
  85. gettarget () {
  86.     while [ "$response" != "y" ]; do
  87.         read -p "Enter the device to clone to [/dev/sdx]: " targetdevice
  88.         targetdevice=${targetdevice:-/dev/sdx}
  89.         read -p "Is $targetdevice correct [y/N]? " response
  90.         response=${response:-N}
  91.         response="${response:0:1}"
  92.         response="${response,,}"
  93.     done
  94. }
  95. #***********************end gettarget****************************
  96.  
  97. #************************checktarget*****************************
  98. checktarget () {
  99.     numtargetpartitions=$(lsblk -nlpo NAME,TYPE $targetdevice | awk '$2=="part"{print $1}' | wc -l)
  100.  
  101.     if [[ $targetdevice == *"nvme"* ]]; then
  102.         efipartition="$targetdevice"p1
  103.         mainpartition="$targetdevice"p2
  104.     else
  105.         efipartition="$targetdevice"1
  106.         mainpartition="$targetdevice"2
  107.     fi
  108.  
  109.     efishort=$(echo $efipartition | awk -F'/' '{print $3}')
  110.     mainshort=$(echo $mainpartition | awk -F'/' '{print $3}')
  111.  
  112.     part1type=$(lsblk -o name,parttypename | grep $efishort | awk -F "$efishort" '{print $2}' | sed 's/^[[:space:]]*//')
  113.  
  114.     part2type=$(lsblk -o name,parttypename | grep $mainshort | awk -F "$mainshort" '{print $2}' | sed 's/^[[:space:]]*//')
  115.  
  116.     if [[ $part1type != "EFI System"  || $part2type != "Linux filesystem" ]]; then
  117.         targetneedsformatted="true"
  118.     else
  119.         targetneedsformatted="false"
  120.     fi
  121. }
  122. #**********************end checktarget***************************
  123.  
  124. #*****************askifformatdesired*************************
  125. askifformatdesired () {
  126.  
  127.     if [[ $targetneedsformatted == "true" ]]; then
  128.         echo -e "\n"
  129.         read -p "Target device ($targetdevice) needs formatting, is that okay? [y/N]: " formatRequested
  130.         formatRequested=${formatRequested:-N}
  131.         formatRequested="${formatRequested:0:1}"
  132.         formatRequested="${formatRequested,,}"
  133.         if [[ $formatRequested != "y" ]]; then
  134.             echo "Format needed but refused, aborting."
  135.             exit;
  136.         fi
  137.     else #format not needed but still an option
  138.         echo -e "\nTarget has preexisting clone."
  139.         echo -e "Preexisting clone can either be refreshed or created anew. (default is to refresh the existing clone)"
  140.         read -p "Format and create a new clone? [y/N]: " formatRequested
  141.         formatRequested=${formatRequested:-N}
  142.         formatRequested="${formatRequested:0:1}"
  143.         formatRequested="${formatRequested,,}"
  144.     fi
  145. }
  146. #**************end askifformatdesired************************
  147.  
  148. #*******************doformat************************
  149. doformat () {
  150.     possiblelabel="$(hostname)usb"
  151.     echo
  152.     read -p "Enter a new label for the target device (e.g. [$possiblelabel]): " label
  153.     label=${label:-$possiblelabel}
  154.     echo "Label of target device will be: $label"
  155.     echo "This might take a few minutes, please be patient."
  156.     fdisk $targetdevice <<EOF
  157. g
  158. n
  159. 1
  160.  
  161. +512M
  162. t
  163. C12A7328-F81F-11D2-BA4B-00A0C93EC93B
  164. n
  165. 2
  166.  
  167.  
  168. w
  169. EOF
  170.  
  171.     echo "efi and ext4 partitions created successfully."
  172.     echo "The new partitions will now be formatted"
  173.     echo "This might take a few minutes, please be patient."
  174.     mkfs.fat -F32 -n EFI "$efipartition"
  175.     yes | mkfs.ext4 -L "$label" "$mainpartition"
  176.     sync
  177.  
  178. }
  179. #******************end doformat*********************
  180.  
  181. #*******************doclone************************
  182. doclone () {
  183. echo "making the clone"
  184.     label="target"
  185.     mount /boot/efi
  186.     mkdir -p /media/$user/EFI
  187.     mount "$efipartition" /media/$user/EFI
  188.     mkdir -p /media/$user/$label
  189.     mount "$mainpartition" /media/$user/$label
  190.  
  191.     sourceuuid=$(findmnt / -o UUID -n)
  192.     targetuuid=$(findmnt /media/$user/"$label" -o UUID -n)
  193.  
  194.     sourceefiuuid=$(grep /boot/efi /etc/fstab | awk '{print $1}' | grep UUID | sed -E 's/UUID=(.*)/\1/' )
  195.     targetefiuuid=$(findmnt /media/$user/EFI/ -o UUID -n)
  196.  
  197.     rsync -rv --delete /boot/efi/ /media/$user/EFI/
  198.    
  199. #trying to make it more distro independent... not well tested
  200.     find /media/$user/EFI/ -name "grub.cfg" -exec sed -i "s/$sourceuuid/$targetuuid/" "{}" \;
  201. #old way proven to work on my Mint Mate installation but wouldn't work if grub.cfg is inside a differently named folder
  202. #    sed -i "s/$sourceuuid/$targetuuid/" /media/$user/EFI/EFI/ubuntu/grub.cfg
  203.      
  204.     rsync -axAXHv --exclude='/dev/*' --exclude='/proc/*' --exclude='/sys/*' --exclude='/tmp/*' --exclude='/run/*' --exclude='/mnt/*' --exclude='/media/*' --exclude='/lost+found/' --delete  / /media/$user/"$label"/
  205.  
  206.     sed -i "s/$sourceuuid/$targetuuid/" /media/$user/$label/etc/fstab
  207.     sed -i "s/$sourceuuid/$targetuuid/" /media/$user/$label/boot/grub/grub.cfg
  208.     sed -i "s/$sourceefiuuid/$targetefiuuid/" /media/$user/$label/etc/fstab
  209.  
  210.     echo "Writing changes to target, do not remove!"
  211.  
  212.     sync
  213. }
  214.  
  215. #*******************doclone************************
  216.  
  217. #*******************fixgrub************************
  218. fixgrub () {
  219.  
  220. for i in /sys /run /dev /proc; do mount --bind "$i" "/media/$user/target$i"; done
  221.  
  222. chroot /media/$user/target/ /bin/bash -- << EOT
  223.     update-grub
  224. EOT
  225.  
  226. for i in /proc /dev /run /sys; do umount "/media/$user/target$i"; done
  227.  
  228. umount /media/$user/EFI
  229. umount /media/$user/target
  230.  
  231. rmdir /media/$user/target
  232. rmdir /media/$user/EFI
  233.  
  234. echo "It is now okay to remove the target drive."
  235. }
  236.  
  237. #*****************end fixgrub**********************
  238.  
  239. main
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement