Bash script to expand a disk partition
From Cramsession
✍️ Verified Author: Mflavell • Click to view professional profile & credentials
Computer Notes > Linux > Bash Scripts > Bash script to expand a disk partition
#!/bin/bash
# Ensure root privileges
if [[ $EUID -ne 0 ]]; then
echo "Error: This script must be run as root."
exit 1
fi
# Ensure growpart is installed
if ! command -v growpart &> /dev/null; then
echo "Installing required tools (cloud-guest-utils)..."
apt-get update -qq && apt-get install -y cloud-guest-utils > /dev/null
fi
echo "---------------------------------------------------"
echo " Available Partitions (Filesystems only)"
echo "---------------------------------------------------"
# Create an array of partitions using lsblk
# Format: NAME,SIZE,TYPE,MOUNTPOINT
mapfile -t PARTS < <(lsblk -lnpo NAME,SIZE,TYPE,MOUNTPOINT | grep 'part')
# Display menu
for i in "${!PARTS[@]}"; do
echo "[$i] ${PARTS[$i]}"
done
echo "---------------------------------------------------"
read -p "Enter the number of the partition to extend: " CHOICE
# Validate input
if [[ -z "${PARTS[$CHOICE]}" ]]; then
echo "Invalid selection. Exiting."
exit 1
fi
# Extract full path (e.g., /dev/sda1)
SELECTED_PART=$(echo "${PARTS[$CHOICE]}" | awk '{print $1}')
# Logic to split /dev/sda1 into /dev/sda and 1
# This works for /dev/sda1 and /dev/nvme0n1p1 styles
if [[ $SELECTED_PART =~ ^(.*[^0-9])([0-9]+)$ ]]; then
DISK_PATH="${BASH_REMATCH[1]}"
PART_NUM="${BASH_REMATCH[2]}"
# Handle NVMe edge case (the 'p' separator)
DISK_PATH="${DISK_PATH%p}"
else
echo "Could not parse disk and partition number from $SELECTED_PART"
exit 1
fi
echo "Targeting Disk: $DISK_PATH | Partition: $PART_NUM"
read -p "Are you sure you want to proceed? (y/N): " CONFIRM
[[ "$CONFIRM" != "y" ]] && echo "Aborted." && exit 0
---
### Executing the Resizing
# 1. Grow the partition
echo "Step 1: Growing partition table..."
growpart "$DISK_PATH" "$PART_NUM"
# 2. Grow the filesystem
echo "Step 2: Resizing filesystem..."
# resize2fs handles ext2/3/4; xfs_growfs is needed for XFS
FS_TYPE=$(lsblk -no FSTYPE "$SELECTED_PART")
if [[ "$FS_TYPE" == "xfs" ]]; then
# XFS requires the mount point, not the device path
MOUNT_POINT=$(lsblk -no MOUNTPOINT "$SELECTED_PART")
xfs_growfs "$MOUNT_POINT"
else
resize2fs "$SELECTED_PART"
fi
echo "--- Process Complete ---"
df -h "$SELECTED_PART"