Disk Information Retrieval.
Document writer <olivier.nicolas@insa-lyon.fr>
v1.0, 2022-11-24
Description.
Description of the process to retrieve the disk information that will be used when either creating (or flashing) an image; mainly, the last sector and the size of the image.
For that we extract the information from the output of sudo fdisk -l /dev/…

get_disk_info.sh
#!/bin/bash # $1 is the device/image # for example: /dev/sdb get_disk_info () { sudo fdisk -l $1 > fdisk.txt # Line containing the word Device # Example: # Device Start End Sectors Size Type Device_Line_Number=$(grep -n "^Device" fdisk.txt | tr ":" "\n"|head -n 1) Line_Count=$(cat fdisk.txt|wc -l) Partition_Count=$(expr $((Line_Count)) - $((Device_Line_Number))) Start_First_Char_Position=$(grep "^Device" fdisk.txt | grep -b -o Start | cut -d ":" -f1) Last_Sector_First_Char_Position=$(expr $((Start_First_Char_Position)) + 6) End_First_Char_Position=$(grep "^Device" fdisk.txt | grep -b -o End | cut -d ":" -f1) Last_Sector_Last_Char_Position=$(expr $((End_First_Char_Position)) + 3) Last_Sector=$(tail -n $Partition_Count fdisk.txt | cut -c$Last_Sector_First_Char_Position-$Last_Sector_Last_Char_Position | sort -n | tail -n 1) Last_Partition_Line_Number=$(tail -n $Partition_Count fdisk.txt | grep -n $Last_Sector | cut -d ":" -f1) # Get, out of the last *Last_Part__Line_Number lines* of the *Partition_Count* lines, the last line; # Which will be the line containing $END # Then get the first "word"; that will be the partition containing the word $END, aka the last partition Last_Partition=$(tail -n $Partition_Count fdisk.txt | head -n $Last_Partition_Line_Number | tail -n 1 | cut -d " " -f1) Last_Partition_Number=$(echo $Last_Partition | grep -Eo '[[:alpha:]]+|[0-9]+' | tail -n 1) Sector_Size=$(grep "Sector size" fdisk.txt | awk '{print $(NF - 4)}') Image_Size=$(( (($Last_Sector + 1)*$Sector_Size) / (1024*1024) )) rm fdisk.txt }
Example:
$ echo $Image_Size 2950
This is the size of the image to be flashed, in MiB. We would use it as such, for example:
$ sudo dd if=/dev/sdb of=/mnt/dest.img bs=1MiB count=$Image_Size conv=fsync
Examples:
A few example results of the following script:
getDriveUsefulSize.sh
#!/bin/bash # $1 is the device/image . ./get_disk_info.sh get_disk_info $1 sudo fdisk -l $1 echo echo Last partition is $Last_Partition, Partition \#$Last_Partition_Number echo It ends at sector $Last_Sector echo echo The size of the image to flash is: $Image_Size MiB
Device Boot Start End Sectors Size Id Type /dev/sdb1 * 0 6041599 6041600 2,9G 0 Empty /dev/sdb2 5268 15283 10016 4,9M ef EFI (FAT-12/16/32) Result: Last partition is /dev/sdb1, Partition #1 It ends at sector 6041599 The size of the image to flash is: 2950 MiB
Device Boot Start End Sectors Size Id Type /dev/sdb1 8192 532479 524288 256M c W95 FAT32 (LBA) /dev/sdb2 532480 3612671 3080192 1,5G 83 Linux Result: Last partition is /dev/sdb2, Partition #2 It ends at sector 3612671 The size of the image to flash is: 1764 MiB
Device Start End Sectors Size Type /dev/sda1 2048 1050623 1048576 512M EFI System /dev/sda2 1050624 33050623 32000000 15,3G Linux swap /dev/sda3 33050624 97050623 64000000 30,5G Linux filesystem /dev/sda4 97050624 1000214527 903163904 430,7G Linux filesystem Result: Last partition is /dev/sda4, Partition #4 It ends at sector 1000214527 The size of the image to flash is: 488386 MiB
This may need improvement in a case like the following depending on if we want the answer to be "1" or "p1".
-
device = /dev/mmcblk0
-
partition = /dev/mmcblk0p1
We could then use code like:
str="/dev/mmcblk0p1" delimiter="/dev/mmcblk0" s=$str$delimiter array=(); while [[ $s ]]; do array+=( "${s%%"$delimiter"*}" ); s=${s#*"$delimiter"}; done; declare -p array echo ${array[1]}
returns p1