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.
1 2 3 4 5 6 7 |
$ 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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
$ fdisk /dev/sdc << FDISK_CMDS g n 1 +64MiB n 2 t 1 83 t 2 83 w FDISK_CMDS |
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
$ sed -e 's/\s*\([\+0-9a-zA-Z]*\).*/\1/' << FDISK_CMDS | sudo fdisk /dev/sdc g # create new GPT partition n # add new partition 1 # partition number # default - first sector +64MiB # partition size n # add new partition 2 # partition number # default - first sector # default - last sector t # change partition type 1 # partition number 83 # Linux filesystem t # change partition type 2 # partition number 83 # Linux filesystem w # write partition table and exit FDISK_CMDS |
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.
1 2 3 4 5 6 7 8 9 10 11 |
$ 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.
1 2 3 4 |
$ 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.
1 |
$ sudo sfdisk --dump /dev/sdc > sdc.dump |
Below is how the dump file looks like.
1 2 3 4 5 6 7 8 9 10 |
$ 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
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
$ 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. |