How to manipulate partition tables with fdisk, cfdisk and sfdisk on Linux

Fdisk, cfdisk and sfdisk are command line partitioning utilities included by default in all Linux distributions. They provide different interfaces to the same set of functions: while they all can be used interactively, only sfdisk is script-oriented. They support DOS, GPT, SGI and SUN partition tables.

In this tutorial we learn how to manipulate partition tables using fdisk, cfdisk and sfdisk, and explore the differences between these tools.

In this tutorial you will learn:

  • How to use fdisk, cfdisk and sfdisk to manipulate partition tables
  • How to use sfdisk to dump and restore a partition table
  • How to list MBR and GPT partition types identifiers
how to manipulate partition tables on linux with fdisk, cfdisk and sfdisk
How to manipulate partition tables on linux with fdisk, cfdisk and sfdisk
Software Requirements and Linux Command Line Conventions
Category Requirements, Conventions or Software Version Used
System Distribution agnostic
Software fdisk/cfdisk/sfdisk
Other Privileged access to your Linux system as root or via the sudo command in order to perform system-wide installation of required packages
Conventions # – requires given linux-commands to be executed with root privileges either directly as a root user or by use of sudo command
$ – requires given linux-commands to be executed as a regular non-privileged user

Using fdisk

The fdisk utility has a dialog-based interface similar to that of gdisk, a tool used to work exclusively on GPT partition tables. We invoke fdisk with the device we want to partition as argument:

$ sudo fdisk /dev/vda

Being dialog-based, fdisk asks us to provide a “command”:

Welcome to fdisk (util-linux 2.38.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0xa8c57b85.

Command (m for help):

Commands are represented by letters. As suggested in the prompt, to obtain the list of the available commands we can use m:

Command (m for help): m

Help:

  DOS (MBR)
   a   toggle a bootable flag
   b   edit nested BSD disklabel
   c   toggle the dos compatibility flag

  Generic
   d   delete a partition
   F   list free unpartitioned space
   l   list known partition types
   n   add a new partition
   p   print the partition table
   t   change a partition type
   v   verify the partition table
   i   print information about a partition

  Misc
   m   print this menu
   u   change display/entry units
   x   extra functionality (experts only)

  Script
   I   load disk layout from sfdisk script file
   O   dump disk layout to sfdisk script file

  Save & Exit
   w   write table to disk and exit
   q   quit without saving changes

  Create a new label
   g   create a new empty GPT partition table
   G   create a new empty SGI (IRIX) partition table
   o   create a new empty DOS partition table
   s   create a new empty Sun partition table

Changes performed with fdisk are kept in memory until we explicitly decide to write them to disk, using the w command.

Fdisk usage example

Let’s see an example of how to use fdisk to create a partition table with just one partition. Nowadays, the most used partition tables are GPT and DOS. We can create both very easily with fdisk. To create a GPT partition table, for example, we use the g command:

Command (m for help): g

Created a new GPT disklabel (GUID: 13A45576-AEFE-EC40-BEDB-A0E21BA01F26).

To create a partition, instead, we usen, and provide:

  1. The partition type (primary vs extended – only on DOS partition tables)
  2. The partition number
  3. The first sector to use for the partition
  4. The last sector to use for the partition (more practically, its size)



All parameters have a default value. The default partition number, for example is 1, while the default first sector used for a partition depends on whether it is the first one on the disk (in that case it is created with an offset of 2048 sectors; the first available sector is used for subsequent partitions). The partition size is expressed by using the “+” or “-” symbols and one among the “K”, “M”, “G”, “T” and “P” suffixes, respectively for: Kibibyte, Mebibyte, Gibibyte. Tebibyte and Pebibyte:

Command (m for help): n
Partition number (1-128, default 1): 
First sector (2048-41943006, default 2048): 
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-41943006, default 41940991):

By default a partition is assigned the “Linux filesystem” type. This can be changed using the t command (see below).

Using cfdisk

Unlike fdisk, cfdisk provides a curses-based interface, which some may consider more user-friendly. As we did for fdisk, we invoke it passing the block device as argument:

$ sudo cfdisk /dev/vda

If the block device doesn’t contain a valid partition table, cfdisk let us select one:

creating a partition table type with cfdisk
Creating a partition table with cfdisk.

We can manage partitions from the “main” interface using the appropriate entries in the bottom menu:

The main cfdisk interface.
The main cfdisk interface.

To change the partition type, we select it and press the t (or T) key, then choose an entry in the dedicated menu:

Choosing a partition type from the cfdisk menu
Choosing a partition type from the cfdisk menu

Using sfdisk

Unlike its companion utilities, sfdisk is script-oriented, so is typically used to perform operations without expecting the user interaction. sfdisk reads commands and instructions from the standard input. When the standard input is a terminal, it runs in interactive mode:

$ sudo sfdisk /dev/vda

Welcome to sfdisk (util-linux 2.38.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Checking that no-one is using this disk right now ... OK

Disk /dev/vda: 20 GiB, 21474836480 bytes, 41943040 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

sfdisk is going to create a new 'dos' disk label.
Use 'label: ' before you define a first partition
to override the default.

Type 'help' to get more information.

>>> 

As when using fdisk and cfdisk, changes are written to disk only when explicitly requested, and “DOS” partition tables are used by default; to switch to GPT, we must execute:

>>> label: gpt

The syntax used to create a partition is pretty simple. The input format must include the following fields, separated by a comma, a space or a semicolon:

<start> <size> <type> <bootable>



The “start” parameter is the partition starting point (expressed in sectors or in one of the available formats we saw before), “size” and “type” are, respectively, the size and type of the partition. Finally, the “bootable” parameter is used to mark the partition as bootable, using the “*” symbol.

Let’s see an example. Suppose we are working on a DOS partition table, and we want to create a boot partition of 1GiB. Here is what we would write:

>>> ,1GiB,83,*

Let’s explain. First of all, we omitted to the first field, so the default starting point is used for the partition. In the second field, we wrote “1GiB”: this is the partition size. In the third field we specified the partition type: in this case we used 83, which is the DOS partition table identifier for the “Linux filesystem” type (GPT identifiers are different, as we will see). Finally, in the fourth field, we used “*”, to mark the partition as bootable. Here is the result of the command:

Created a new partition 1 of type 'Linux' and of size 1 GiB.
   /dev/vda1 :         2048      2099199 (1G) Linux
/dev/vda2:

We can now pass information about the next partition or write the partition table to disk, using the “write” command.

sfdisk in “script” mode

As we already said, sfdisk reads instruction from the standard input, therefore, to run in non-interactive mode, we can pass instructions to it directly. We can replicate what we did in the previous example using a shell pipe:

$ echo ",1GiB,83,*" | sudo sfdisk /dev/vda

We could even use a “here string”:

$ sudo sfdisk /dev/vda <<< ",1GiB,83,*"

Notice however, that such commands always “start from scratch”, so they create a new disk label each time (deleting existing partitions), and that when in “script” mode, sfdisk writes changes to disk immediately. What if we want to add a partition to an existing table then? To accomplish such task we use the --append option. To add a partition to an existing table, and assign it all the remaining space on disk, for example, we would run:

$ echo ",," | sudo sfdisk --append /dev/vda

How to create multiple partitions at once? We can use the same technique, separating each instruction with a newline. In the example below we create a GPT partition table and two partitions with a single command:

$ echo -e "label: gpt\n,1GiB\n," | sudo sfdisk /dev/vda

More conveniently, we could use a “here document” construct, which is more readable by us silly human beings:

sudo sfdisk /dev/vda << EOF
label: gpt
,1GiB
,
EOF

Unlike fdisk and cfdisk, sfdisk, by default, doesn’t erase the first sector of a disk when creating a new partition table. To obtain the same behavior of the other two utilities, it must be invoked with the --wipe always option.

Resizing a partition

Until now we saw how to create partitions from scratch. What about shrinking or enlarging an existing partition? Well, it’s a pretty simple operation if you think of it: all we must do is to use the same parameters we used at creation time. The only thing we need, is a way to reference a specific partition. We can do that with the -N option, passing the partition number as argument. In the previous example we created a GPT partition table with two partitions. The first one had a size of 1GiB. To shrink it to 512MiB, we would run:

$ echo ",512MiB" | sudo sfdisk -N 1 /dev/vda

The output of the command reports the old and the current situation:

Old situation:

Device       Start      End  Sectors Size Type
/dev/vda1     2048  2099199  2097152   1G Linux filesystem
/dev/vda2  2099200 41940991 39841792  19G Linux filesystem

/dev/vda1: 
New situation:
Disklabel type: gpt
Disk identifier: B95D2ECA-1336-6949-89E8-BDC3B493F9A2

Device       Start      End  Sectors  Size Type
/dev/vda1     2048  1050623  1048576  512M Linux filesystem
/dev/vda2  2099200 41940991 39841792   19G Linux filesystem

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

That’s it: instead of specifying the amount of space to subtract or add to the partition, we directly specify its new size. Needless to say, if a filesystem exists on a partition, we need to reduce it before reducing the partition itself.

Dumping and restoring a partition table

We can use sfdisk to dump and restore the partition table of a disk. To perform such action we invoke the utility with the -d option (short for --dump). The configuration is dumped on standard output by default. We may want to redirect it to a file, instead:

$ sudo sfdisk -d /dev/vda > vda_dump.txt

To re-apply the dumped configuration to the disk, we would run:

$ sudo sfdisk /dev/vda < vda_dump.txt

To replicate the partition table on a different disk, we can pipe the output of the command directly to another instance of sfdisk:

$ sudo sfdisk -d /dev/vda | sudo sfdisk /dev/vdb



If we just want to take a look the current partition table, we can invoke sfdisk with the -l option (--list):

$ sudo sfdisk -l /dev/vda
Disk /dev/vda: 20 GiB, 21474836480 bytes, 41943040 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: B95D2ECA-1336-6949-89E8-BDC3B493F9A2

Device       Start      End  Sectors Size Type
/dev/vda1     2048  2099199  2097152   1G Linux filesystem
/dev/vda2  2099200 41940991 39841792  19G Linux filesystem

Partition types

Partition types suggest the purpose of a partition, or the filesystem contained on it. We can list available partition types in different ways, depending on the utility we are using. When using fdisk, for example, we can obtain a list of the available partition types by using l. Hexadecimal identifier are used on DOS partition tables, while GUID are used on GPT. Executing the l command on a GPT partitioned disk, we would obtain the following (truncated) output:

  1 EFI System                     C12A7328-F81F-11D2-BA4B-00A0C93EC93B
  2 MBR partition scheme           024DEE41-33E7-11D3-9D69-0008C781F39F
  3 Intel Fast Flash               D3BFE2DE-3DAF-11DF-BA40-E3A556D89593
  4 BIOS boot                      21686148-6449-6E6F-744E-656564454649
  5 Sony boot partition            F4019732-066E-4E12-8273-346C5641494F
  6 Lenovo boot partition          BFBFAFE7-A34F-448A-9A5B-6213EB736C22
  7 PowerPC PReP boot              9E1A2D38-C612-4316-AA26-8B49521E5A8B
  8 ONIE boot                      7412F7D5-A156-4B13-81DC-867174929325
  9 ONIE config                    D4E6E2CD-4469-46F3-B5CB-1BFF57AFC149
 10 Microsoft reserved             E3C9E316-0B5C-4DB8-817D-F92DF00215AE
 11 Microsoft basic data           EBD0A0A2-B9E5-4433-87C0-68B6B72699C7
 12 Microsoft LDM metadata         5808C8AA-7E8F-42E0-85D2-E1E90434CFB3
 13 Microsoft LDM data             AF9B60A0-1431-4F62-BC68-3311714A69AD
 14 Windows recovery environment   DE94BBA4-06D1-4D40-A16A-BFD50179D6AC
 15 IBM General Parallel Fs        37AFFC90-EF7D-4E96-91C3-2D7AE055B174
 16 Microsoft Storage Spaces       E75CAF8F-F680-4CEE-AFA3-B001E56EFC2D
 17 HP-UX data                     75894C1E-3AEB-11D3-B7C1-7B03A0000000
 18 HP-UX service                  E2A1E728-32E3-11D6-A682-7B03A0000000
 19 Linux swap                     0657FD6D-A4AB-43C4-84E5-0933C84B4F4F
 20 Linux filesystem               0FC63DAF-8483-4772-8E79-3D69D8477DE4
 [...]

On a DOS partitioned disk, the output would be the following:

00 Empty            27 Hidden NTFS Win  82 Linux swap / So  c1 DRDOS/sec (FAT-
01 FAT12            39 Plan 9           83 Linux            c4 DRDOS/sec (FAT-
02 XENIX root       3c PartitionMagic   84 OS/2 hidden or   c6 DRDOS/sec (FAT-
03 XENIX usr        40 Venix 80286      85 Linux extended   c7 Syrinx         
04 FAT16 <32M       41 PPC PReP Boot    86 NTFS volume set  da Non-FS data    
05 Extended         42 SFS              87 NTFS volume set  db CP/M / CTOS / .
06 FAT16            4d QNX4.x           88 Linux plaintext  de Dell Utility   
07 HPFS/NTFS/exFAT  4e QNX4.x 2nd part  8e Linux LVM        df BootIt         
08 AIX              4f QNX4.x 3rd part  93 Amoeba           e1 DOS access     
09 AIX bootable     50 OnTrack DM       94 Amoeba BBT       e3 DOS R/O        
0a OS/2 Boot Manag  51 OnTrack DM6 Aux  9f BSD/OS           e4 SpeedStor      
0b W95 FAT32        52 CP/M             a0 IBM Thinkpad hi  ea Linux extended 
0c W95 FAT32 (LBA)  53 OnTrack DM6 Aux  a5 FreeBSD          eb BeOS fs        
0e W95 FAT16 (LBA)  54 OnTrackDM6       a6 OpenBSD          ee GPT            
0f W95 Ext'd (LBA)  55 EZ-Drive         a7 NeXTSTEP         ef EFI (FAT-12/16/
10 OPUS             56 Golden Bow       a8 Darwin UFS       f0 Linux/PA-RISC b
11 Hidden FAT12     5c Priam Edisk      a9 NetBSD           f1 SpeedStor      
12 Compaq diagnost  61 SpeedStor        ab Darwin boot      f4 SpeedStor      
14 Hidden FAT16 <3  63 GNU HURD or Sys  af HFS / HFS+       f2 DOS secondary  
16 Hidden FAT16     64 Novell Netware   b7 BSDI fs          f8 EBBR protective
17 Hidden HPFS/NTF  65 Novell Netware   b8 BSDI swap        fb VMware VMFS    
18 AST SmartSleep   70 DiskSecure Mult  bb Boot Wizard hid  fc VMware VMKCORE 
1b Hidden W95 FAT3  75 PC/IX            bc Acronis FAT32 L  fd Linux raid auto
1c Hidden W95 FAT3  80 Old Minix        be Solaris boot     fe LANstep        
1e Hidden W95 FAT1  81 Minix / old Lin  bf Solaris          ff BBT            
24 NEC DOS



To know the available types when using sfdisk, instead, we can use the -T option, and pass the partition label type as argument to --label. For example, to obtain the list of the partition types for GPT and their GUID, we would run:

$ sfdisk -T --label gpt

A series of alias for partition types exist for convenience. They automatically assume the appropriate value depending on the partition table in use:

PARTITION TYPE ALIAS MBR ID GPT GUID
linux L 83 0FC63DAF-8483-4772-8E79-3D69D8477DE4
swap S 82 0657FD6D-A4AB-43C4-84E5-0933C84B4F4F
extended Ex 05  –
home H 933AC7E1-2EB4-4F13-B844-0E14E2AEF915
uefi U EF C12A7328-F81F-11D2-BA4B-00A0C93EC93B
raid R FD A19D880F-05FC-4D3B-A006-743F0F84911E
lvm V 8E E6D6D379-F507-44C2-A23C-238F2A3DF928

Conclusions

In this tutorial we learned how to manipulate partition tables using three similar utilities which comes preinstalled in all Linux distributions: fdisk, cfdisk and sfdisk. The first two are designed to work interactively; the third, sfdisk, is script-oriented.



Comments and Discussions
Linux Forum