Linux: Script to Partition Disk

Objective: Automate the partitioning of a disk using a script on Linux.

There are primarily 3 common utilities to partition a disk on Linux. They are: fdisk, sfdisk and parted. We will cover all three of them in this article. cfdisk can also be used for disk partitioning, but it’s a curses based program and will not be covered here.

I created a small 128MB disk on a VM. Let’s say that I want to create 2 primary partitions of 64MB each using GPT partition table. Let’s see how we can script this.

First, let’s make sure that no partitions are defined in the new disk. In this example, we are going to use /dev/sdc for the new disk.

$ sudo fdisk -l /dev/sdc
Disk /dev/sdc: 128 MiB, 134217728 bytes, 262144 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x08c2ed50

Partition Using fdisk

fdisk is able to read commands from stdin (standard input), so what we will need to do is to feed commands to fdisk to create the partitions.

The lines between FDISK_CMDS above are actual commands that would normally be typed on the fdisk prompt. It definitely looks cryptic. Below is a better version with comments.

For the command format above, sed will strip the comments before passing the commands to fdisk.

Let’s look at the partition table after running the above command. Two partitions are created under GPT.

$ sudo fdisk -l /dev/sdc
Disk /dev/sdc: 128 MiB, 134217728 bytes, 262144 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: B3EC5118-1E50-423A-ACB5-06A3E299F5EA

Device      Start    End Sectors Size Type
/dev/sdc1    2048 133119  131072  64M Linux filesystem
/dev/sdc2  133120 262110  128991  63M Linux filesystem

Partition Using parted

To script the partition layout using parted, we can make use of the mklabel and mkpart commands.

$ sudo parted --script /dev/sdc \
mklabel gpt \
mkpart primary ext4 1MiB 65MiB \
mkpart primary ext4 65MiB 134MB 

Partition Using sfdisk

Lastly, we will script the disk partioning using sfdisk. sfdisk is a script-oriented tool for partitioning devices.

To use sfdisk, I find it easier to manually create the partition layout, dump the layout to a file, and then use the dump file to create partitions.

To dump the partitions of /dev/sdc, run sfdisk using --dump option.

$ sudo sfdisk --dump /dev/sdc > sdc.dump

Below is how the dump file looks like.

$ cat sdc.dump 
label: gpt
label-id: 3E648FBD-0C5C-4853-9683-27BBE390366A
device: /dev/sdc
unit: sectors
first-lba: 2048
last-lba: 262110

/dev/sdc1 : start=        2048, size=      131072, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=B69ED9C7-0E0E-4075-959B-F96867AD81A4
/dev/sdc2 : start=      133120, size=      128991, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=B32E8676-DC9A-45C9-96B6-66B8035110BB

To partition the disk using the dump file, use the dump file as an input to sfdisk.

$ cat sdc.dump | sudo sfdisk /dev/sdc
Checking that no-one is using this disk right now ... OK

Disk /dev/sdc: 128 MiB, 134217728 bytes, 262144 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xfca5c5f6

Old situation:

>>> Script header accepted.
>>> Script header accepted.
>>> Script header accepted.
>>> Script header accepted.
>>> Script header accepted.
>>> Script header accepted.
>>> Created a new GPT disklabel (GUID: 3E648FBD-0C5C-4853-9683-27BBE390366A).
Created a new partition 1 of type 'Linux filesystem' and of size 64 MiB.
/dev/sdc2: Created a new partition 2 of type 'Linux filesystem' and of size 63 MiB.
/dev/sdc3: 
New situation:

Device      Start    End Sectors Size Type
/dev/sdc1    2048 133119  131072  64M Linux filesystem
/dev/sdc2  133120 262110  128991  63M Linux filesystem

The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

ibrahim = { interested_in(unix, linux, android, open_source, reverse_engineering); coding(c, shell, perl, php, python, java, javascript, nodejs, angular, react); plays_on(xbox, ps4); linux_desktop_user(true); }