Bash script to expand a disk partition

From Cramsession
Jump to navigationJump to search
✍️ Verified Author: MflavellClick 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"