Script GPT Changes Safely with sgdisk

sgdisk edits a GPT disk from a script, with no confirmation prompt to catch a typo before it writes. This walks through inspecting a disk, making a small partition-table change, verifying the result and keeping a binary backup. The examples use a disposable raw image first, so you learn the command order without touching a real disk. On this machine the installed package is gdisk 1.0.10-1build1, providing GPT fdisk sgdisk 1.0.10.

Allow 15 minutes for the image exercise, longer if you are prepping a production disk. You need a shell, the gdisk package and enough free space for a test image. Real block-device changes normally need elevated privileges and can leave a system unbootable, so read the target device name twice before you reach for sudo.

1. Confirm the installed command

Start with a read-only version check. No device required:

$ sgdisk --version
GPT fdisk (sgdisk) version 1.0.10

The manual page shipped with this installation is dated for version 1.0.10. Options and output can differ in another release, so keep the version noted when documenting an automated job.

Checkpoint: if sgdisk --version fails, stop here and install or repair the package through your normal distribution process. Do not substitute an unverified partitioning utility in a script.

2. Inspect a disk before changing it

Use a real device path only once you have checked it independently. -p prints the basic GPT summary; -v checks CRCs, the main and backup data and other consistency conditions:

$ sudo sgdisk -p /dev/disk/by-id/REPLACE_WITH_THE_EXACT_DISK
$ sudo sgdisk -v /dev/disk/by-id/REPLACE_WITH_THE_EXACT_DISK

Expected verification ends with text like No problems found. and reports free sectors. The command can still print useful information for a damaged or non-GPT table, so a clean result is not proof the filesystem data or boot configuration is healthy. Check the device mapping with lsblk or your platform's inventory tool before going further.

Do not use a partition such as /dev/sda1 where a whole-disk device is required. sgdisk writes GPT headers and partition entries, not filesystems, so an entry is not usable storage until something else formats it separately.

3. Practise on a disposable raw image

A raw image is a safe place to test option syntax. This creates a 64 MiB file in /tmp; it does not touch a real block device:

$ test_image=$(mktemp /tmp/sgdisk-guide.XXXXXX.img)
$ truncate -s 64M "$test_image"
$ sgdisk --clear \
    --new=1:0:+20M \
    --change-name=1:Data \
    --typecode=1:8300 \
    "$test_image"

--clear creates an empty GPT layout in the new image. --new=1:0:+20M asks for partition 1, starting at the default position in the largest available block and ending 20 MiB after that. Code 8300 is GPT fdisk's Linux filesystem type code: it just labels the entry, it does not format anything.

On a file, successful output includes Creating new GPT entries in memory. and The operation has completed successfully. Here is the surprising part: the command writes immediately. Unlike interactive gdisk, sgdisk gives you no review step before saving.

Print the resulting table:

$ sgdisk --print "$test_image"
Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048           43007   20.0 MiB    8300  Data

Sector numbers shift with image size and alignment. What actually matters: partition 1 exists, is named Data, carries code 8300 and is close to 20 MiB.

4. Back up the current GPT before further work

Save the partition data to a separate file before making another change:

$ sgdisk --backup=/path/to/REPLACE_WITH_A_SAFE_BACKUP.bin "$test_image"
$ stat --format='%n %s bytes' /path/to/REPLACE_WITH_A_SAFE_BACKUP.bin

The backup holds the protective MBR, both GPT headers and one copy of the partition table. It is a binary partition-table backup, not a copy of the partition contents, so store it somewhere that survives loss of the source disk. It describes the in-memory table at the moment the command runs, so take it after the changes you actually want kept.

Checkpoint: record the backup path and confirm the file is non-empty. Never overwrite a known-good backup with a command whose device argument has not been checked.

5. Preview a destructive or uncertain change

Use --pretend when you want the in-memory result without writing it. This previews deleting partition 1:

$ sgdisk --pretend --delete=1 "$test_image"
$ sgdisk --print "$test_image"
Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048           43007   20.0 MiB    8300  Data

The second command still shows the partition because the pretend run was never persistent. Treat this as a rehearsal, not a confirmation prompt. On a real disk, the equivalent write command is irreversible at the partition-table level unless you already have a verified backup:

$ sudo sgdisk --delete=1 /dev/disk/by-id/REPLACE_WITH_THE_EXACT_DISK

Warning: deleting an entry removes the partition definition but does not erase the sectors that used to belong to it. That is not the same as making the data safe: filesystems lose their normal path to it, and later reuse can overwrite it. Stop if the target holds mounted filesystems, swap, a boot partition or anything you have not backed up.

6. Verify after a real change

For a production edit, rerun the print and verify commands, then check the operating system's own view of the device:

$ sudo sgdisk --print /dev/disk/by-id/REPLACE_WITH_THE_EXACT_DISK
$ sudo sgdisk --verify /dev/disk/by-id/REPLACE_WITH_THE_EXACT_DISK
$ lsblk -o NAME,PATH,SIZE,FSTYPE,MOUNTPOINTS /dev/REPLACE_WITH_THE_KERNEL_DISK

Look for the intended partition number, start, end, type and name. Here is the trap: a successful sgdisk write can leave the kernel using its old partition table until a rescan or reboot, exactly as the command's own warning explains. Do not guess at a rescan while partitions are mounted. Follow your distribution's documented storage procedure, and confirm no service is using the device before asking the kernel to reread it.

7. Restore only with the correct backup

If the table needs restoring, use the backup made from that same disk and confirm both paths before running the write:

$ stat /path/to/REPLACE_WITH_THE_MATCHING_BACKUP.bin
$ sudo sgdisk --load-backup=/path/to/REPLACE_WITH_THE_MATCHING_BACKUP.bin /dev/disk/by-id/REPLACE_WITH_THE_EXACT_DISK
$ sudo sgdisk --verify /dev/disk/by-id/REPLACE_WITH_THE_EXACT_DISK

Loading a backup from another disk is unsafe: it can reproduce that other disk's layout and GUIDs on this one. Keep the original backup until the restored table and the filesystems have been checked. A partition-table restore never restores overwritten file data, so it is no substitute for a filesystem or image backup.

Common traps

Done means