How I used fdisk in a script to partition a drive
Image by Gerd Altmann on Pixabay.
As you probably know by now, I believe in automating everything. So when one of my scripts failed to properly partition and create an EXT4 filesystem on a new 4GB external USB hard drive, I was surprised — but I shouldn’t have been.
The problem
As usual, this problem was one of my own making. I use these external USB hard drives for my backups. The script performs some preparation steps on the drives. It deletes existing partitions, creates a new one that fills the entire disk, and installs an EXT4 filesystem on the partition. Except that I had previously only used the script on drives of 2TB or less. I prepared a couple 4TB drives before writing my script so I didn’t catch the problem until now, when I tried to prepare a new 4TB drive.
I’d used sfdisk in the script because it is allegedly designed to be used in scripts. But I hadn’t specified use of GPT in the command, and that’s required for drives over 2TB. I tried using sfdisk as a regular command with options and arguments, but that failed. The sfdisk command can also use a bit of magic with a “here document” to hold the commands that need to be used in the command. But that also failed to work.
It did work — sort of — by creating a 2TB partition. Therefore, I’m not so sure sfdisk really designed to be used in scripts — at least not easily.
The bottom line here is that I was never able to determine the correct wizardly incantation to create the proper partition. No amount of Internet searching provided a working answer.
The solution
My searches did result in a potential solution using the ancient and venerated fdisk command. It also requires a here document, but it’s much easier to create and understand.
The fdisk command requires a here document to contain the required commands. This was easy because I frequently use those commands frequently to prepare many types of storage devices. I use the wipefs command to wipe all existing partitions from the storage device. I could do this with fdisk in the here document, but I never know how many partitions already exist.
Here’s an annotated version of my code. The first EOF specifies the text code to delimit the end of the file. The second instance is the end of the file. Any text will do, but EOF seems to be the most common delimiter. Note the use of << to redirect input from STDIO to the command. $Device contains the name of the device special file for the device you’re preparing.
# Deleting all partitions
wipefs -a /dev/$Device
sync ; sync # Always sync storage devices twice to ensure that everything is truly written
# to the device.
# Create new Linux GPT partition
echo "Creating new partition on $Device"
fdisk /dev/$Device << EOF
g # Create a GPT signature and partition table.
p # Print the current state.
n # Create a new partition.
# The default partition is 1 so just hit Enter. Blank lines are "Enter."
# Enter to use the default first sector number.
# Enter to use the default last sector number. This should fill the entire storage device.
p # Print the new partition information
w # Write the new partitioning scheme to the device.
EOF
sync ; sync
Be sure to use the -a option in the wipefs command. Also, the trailing EOF delimiter must be on the left margin and start in the first column. I got errors until I figured that out.
To use this here document, remove all comments between the two EOF delimiters. It should look like this on the command line and in your script.
fdisk /dev/$Device << EOF
g
p
n
p
w
EOF
Summary
This works well for me and does exactly what I need it to. It’s also a good illustration of using redirection to provide input to a command that’s designed to be interactive like fdisk.