Partition a Disk Image Safely with sfdisk
You will create and inspect a small GPT partition table in a disposable disk image, using the same script you could later review for a real device. The workflow covers dry runs, alignment, backups and verification without asking you to experiment on a live disk. Allow about fifteen minutes. You need sfdisk from util-linux and enough space for a test image; the installed command here is util-linux 2.42.4.
The route
Jump straight to the step you need, or tick off Done means at the end.
Safety boundary
Partition-table changes are destructive. The commands below use a regular file under /tmp, not a block device. Do not replace the image path with /dev/sda, /dev/nvme0n1 or another real device until you have a verified backup and a maintenance plan. Creating a filesystem is a separate operation and is deliberately not included.
1. Confirm the installed tool
Check which executable will run and record its version. These are ordinary, read-only commands:
$ command -v sfdisk
/home/linuxbrew/.linuxbrew/sbin/sfdisk
$ sfdisk --version
sfdisk from util-linux 2.42.4
Your path can differ. The local manual documents GPT, DOS, SUN and SGI labels, script input and the options used here. It also says that sfdisk aligns starts and ends when you use relative sizes or multiplicative suffixes such as MiB. For portable scripts, let sfdisk choose starts and express sizes in MiB or GiB unless you specifically need sector offsets.
2. Create a disposable image
Make a 100 MiB regular file. This changes only the temporary file and does not require elevated privileges:
$ IMAGE=/tmp/sfdisk-demo.img
$ truncate -s 100M "$IMAGE"
$ stat --format='size=%s bytes' "$IMAGE"
size=104857600 bytes
Keep IMAGE set in the same shell for the remaining examples. A regular file is useful for learning and review, but it is not a complete simulation of a kernel block device: there are no partition nodes to mount, and options concerning kernel rereads have limited meaning.
3. Dry-run a GPT script
The input below requests a GPT label, a 32 MiB Linux partition, then a second partition using the remaining space. The blank start fields let sfdisk align the layout. L is the documented Linux type shortcut; in GPT output it becomes the Linux filesystem type GUID.
$ printf 'label: gpt\n,32M,L\n,\n' \
| sfdisk --no-act --no-reread "$IMAGE"
Disk /tmp/sfdisk-demo.img: 100 MiB, 104857600 bytes, 204800 sectors
Created a new GPT disklabel
/tmp/sfdisk-demo.imgp1: Created a new partition 1 of type 'Linux filesystem' and of size 32 MiB
/tmp/sfdisk-demo.imgp2: Created a new partition 2 of type 'Linux filesystem' and of size 66 MiB
The partition table is unchanged (--no-act).
The exact disk identifier and some formatting vary. The useful checkpoint is the final unchanged message. --no-act performs the operation except writing to the device or file, so this is the point to catch a wrong size, label or target path.
4. Apply the reviewed layout
Read the same script again, this time allowing the write. --lock=nonblock requests the recommended device lock but does not wait if another process holds it. On a real device, use the default blocking lock or stop and investigate a lock failure; do not work around a process that may be using the disk.
$ printf 'label: gpt\n,32M,L\n,\n' \
| sfdisk --no-reread --lock=nonblock "$IMAGE"
The partition table has been altered.
This is the first state-changing command. On a real block device it can make existing data inaccessible and may notify the kernel about the new table. The manual recommends locking to avoid races with systemd-udevd and other tools. --no-reread is useful for a regular image here; it is not a general solution for changing a mounted or otherwise busy disk.
5. Inspect and verify the result
List the table, then ask sfdisk to check its consistency:
$ sfdisk --no-reread --list "$IMAGE"
Disklabel type: gpt
Device Start End Sectors Size Type
/tmp/sfdisk-demo.imgp1 2048 67583 65536 32M Linux filesystem
/tmp/sfdisk-demo.imgp2 67584 202751 135168 66M Linux filesystem
$ sfdisk --no-reread --verify "$IMAGE"
/tmp/sfdisk-demo.img:
No errors detected.
Sector numbers are the authoritative detail. The first partition starts at sector 2048 here, which is a 1 MiB boundary with 512-byte sectors. The last partition does not consume the GPT backup area, so the usable size is smaller than the file size.
For scripts and monitoring, request JSON rather than scraping aligned columns:
$ sfdisk --no-reread --json "$IMAGE" \
| jq '.partitiontable.partitions | length'
2
The JSON is output only: sfdisk cannot use JSON as input. If jq is unavailable, save the output and inspect it as JSON with a tool you already trust.
6. Save a restoreable description
A dump is a text script containing the label, sector geometry, types and partition UUIDs. Save it before making a planned change:
$ sfdisk --no-reread --dump "$IMAGE" > /tmp/sfdisk-demo.dump
$ sed -n '1,12p' /tmp/sfdisk-demo.dump
label: gpt
label-id: ...
device: /tmp/sfdisk-demo.img
unit: sectors
first-lba: 2048
To restore that dump, first confirm that the target path is the intended disposable image, then run sfdisk "$IMAGE" < /tmp/sfdisk-demo.dump. A restore reproduces partition types and UUIDs. Do not clone the same dump to several machines without considering duplicate UUIDs; the manual explicitly warns that this can cause problems.
For a binary backup of the sectors holding the table, use --backup-pt-sectors. Keep that raw backup separate from the image. Restoring raw sectors uses dd and an exact device offset, so it is an expert recovery operation: verify the device several times and do not improvise the offset from memory.
7. Avoid the common traps
- An omitted start is not sector zero. sfdisk normally chooses the first available aligned sector; the first default start is 1 MiB.
- An omitted size means as much space as possible. A numeric size without a suffix is a number of sectors;
32Mis a byte-sized value that is aligned. --label gptdoes not by itself create an empty label. An input containing onlylabel: gptexplicitly requests an empty table; otherwise include partition lines.--forcedisables consistency checking. It is not a routine fix for a warning. Stop, back up and understand the layout first.--wipeand--wipe-partitionscan erase signatures. Leave their defaults alone unless you have deliberately planned that data loss.
If you made a mistake in the disposable image, discard that image and recreate it. On a real disk there is no universal undo: restore a verified dump or binary table backup only after stopping services, unmounting affected filesystems and confirming the exact target.
Done means
- You checked the installed sfdisk version and target path.
- You dry-ran the script and reviewed its label, sizes and partition count.
- You applied it only to a disposable image, then listed and verified the table.
- You saved a dump before treating the layout as recoverable.
- You understand which omitted values sfdisk chooses and which options can erase signatures.