脚本说明

主要功能:自动扩展Linux系统中未分区的磁盘空间


注意事项:

  1. 该脚本默认会将所有剩余空间扩容到你选择的分区上,请注意
  2. 默认只支持 xfs 和 ext 格式的文件系统

控制流图

auto_fdisk_mermaid.png

脚本

#!/bin/bash
#########################################
## AUTO PARTITION FOR LINUX SINGLE DISK WITH UNPARTITIONED SPACE 2024-11-15
## email: levywang@foxmail.com
## levywang
## centos 7 & 8 and Ubuntu 18.04 Later
#########################################

# Set variables
export LANG=en_US.UTF-8
source /etc/os-release

# Check if commands are installed
type growpart >/dev/null 2>&1 || (yum install -y cloud-utils-growpart >/dev/null 2>&1 || apt install -y cloud-guest-utils >/dev/null 2>&1)
type gdisk >/dev/null 2>&1 || (yum install -y gdisk >/dev/null 2>&1 || apt install -y gdisk >/dev/null 2>&1)
type lvdisplay >/dev/null 2>&1 || (yum install -y lvm2 >/dev/null 2>&1 || apt install -y lvm2 >/dev/null 2>&1)
type xfs_growfs >/dev/null 2>&1 || (yum install -y xfsprogs >/dev/null 2>&1 || apt install -y xfsprogs >/dev/null 2>&1)

# Display help information
show_help() {
    echo -e "\033[33mUsage: $0 [-help | --help | help]\033[0m"
    echo ""
    echo -e "\033[33mOptions:\033[0m"
    echo "  -help, --help, help  Show this help message and exit"
    echo ""
    echo -e "\033[33mDescription:\033[0m"
    echo "  This script will list available disk partitions and allow the user to select one for expansion."
}

# Check parameters
if [ "$1" = "-help" ] || [ "$1" = "--help" ] || [ "$1" = "help" ]; then
    show_help
    exit 0
fi

# Check FileSystem Type, only xfs and ext4 are supported
check_filesystem() {
  fs_type=$(df -T "$disk_path" 2>/dev/null | awk 'NR==2 {print $2}')

  if [[ "$fs_type" == "ext"*  || "$fs_type" == "xfs" ]]; then
      echo -e "\033[32mSupported filesystem.\033[0m"
      return 0
  else
      echo -e "\033[31mUnsupported filesystem, exit execution.\033[0m"
      exit 1
  fi
}

# Get disk partition information
partitions=($(blkid | grep -v -E "mapper|loop" | awk -F: '{print $1}' | awk -F/ '{print $3}'))
for i in "${partitions[@]}"; do
    df -h | grep $i | grep boot > /dev/null
    if [ $? -eq 0 ]; then
        partitions=(${partitions[*]/$i})
    fi
done

# Check if there are available partitions
if [ ${#partitions[@]} -eq 0 ]; then
    echo -e "\033[31mNo available disk partitions found.\033[0m"
    exit 1
fi

# Provide user selection
/usr/bin/lsblk | grep -v -E 'loop|sr|boot'
echo -e "\033[33mPlease select the disk partition to expand, Ctrl+C cancel:\033[0m"
select disk_name in "${partitions[@]}"; do
    if [ -n "$disk_name" ]; then
        break
    else
        echo -e "\033[31mInvalid selection, please try again.\033[0m"
    fi
done

echo -e "\033[32mYou selected partition: $disk_name\033[0m"

# Confirm user selection
user_confirm() {
read -n1 -p "Confirm the selected partition is correct [Y/y|N/n]? " answer
case $answer in
Y | y) echo
echo -e "\033[32mContinue\033[0m";;
N | n) echo
echo -e "\033[31mGoodbye\033[0m"
exit;;
*) echo
echo -e "\033[31mInvalid input, goodbye\033[0m"
exit;;
esac

sleep 2
}

user_confirm

# Set variables
top_disk_name=$(echo "$disk_name" | sed 's/[0-9]//')
disk_number=$(echo $disk_name | sed 's/[a-z]//g')
disk_total=$(parted -s /dev/$top_disk_name unit TB print | grep 'Disk /dev' | sed 's/[^0-9.]//g')
lv_path=$(lvdisplay | grep "LV Path" | awk '{print $3}')
disk_filesystem_type=xfs
partitions=$(lsblk -n -o NAME /dev/$top_disk_name | grep -v ^$top_disk_name)

# Rescan disk space size for vcenter expansion
if [ -f /sys/class/block/$top_disk_name/device/rescan ]; then
    echo 1 > /sys/class/block/$top_disk_name/device/rescan
fi



# Check if disk space is greater than 2TB
if (( $(echo "$disk_total >= 2" | bc -l) )); then
    # Check partition format
    partition_type=$(sudo parted -s /dev/$top_disk_name print | grep 'Partition Table:' | awk '{print $3}')

    if [ "$partition_type" == "msdos" ]; then
        echo -e "\033[31mDisk space is greater than 2TB, and partition format is MBR. It is recommended to convert to GPT partition format.\033[0m"
        echo -e "\033[31mPlease manually convert the partition format and run the script again.\033[0m"
        exit 1
    else
        echo -e "\033[32mDisk space is greater than 2TB, partition format is GPT, no need to convert partition.\033[0m"
    fi
else
    echo -e "\033[32mDisk space is less than 2TB, no need to convert partition.\033[0m"
fi

# Check if there is unallocated space
unallocated_space=$(sudo parted -s /dev/$top_disk_name unit GB print free | grep 'Free Space' | tail -1 | awk '{print $3}')
if [[ "$unallocated_space" == "0GB" || "$unallocated_space" == "0.00GB" ]]; then
    echo -e "\033[31mNo space available for expansion, please check disk partition situation.\033[0m"
    exit 1
elif [[ -z "$unallocated_space" && -z $partitions ]]; then
    echo -e "\033[31mThe selected disk is a raw device with no partitions.\033[0m"
    disk_type="raw"
else
    echo -e "\033[32mThere is $unallocated_space unallocated space, starting expansion.\033[0m"
fi

# Check if it is an LVM logical volume
lv_num=$(lsblk /dev/$disk_name | grep lvm | wc -l)
if [ $lv_num -ne 0 ]; then
    # Select which logical volume to expand
    echo -e "\033[33mPlease select the logical volume to expand\033[0m"
    select var in $lv_path; do
        break
    done

    # Set filesystem type variable and check filesystem
    if [[ -n "$var" ]]; then
        disk_path=$var
    else
        disk_path=/dev/$disk_name
    fi
    check_filesystem

    # Special handling for Ubuntu root partition
    mount_point=$(grep "/dev/$disk_name /" /proc/mounts | awk '{print $2}')
    if [[ $ID == "ubuntu" && $mount_point == "/" ]]; then
        tmp_disk_path=$(fdisk -lu /dev/$top_disk_name | grep Extended | awk '{print $1}')
        tmp_disk_name=$(echo $tmp_disk_path | awk -F/ '{print $3}' | sed 's/[0-9]//')
        tmp_disk_num=$(echo $tmp_disk_path | awk -F/ '{print $3}' | sed 's/[a-z]//g')
        LC_ALL=en_US.UTF-8 growpart /dev/$tmp_disk_name $tmp_disk_num

    fi

    if [[ "$disk_type" != "raw" ]]; then
        LC_ALL=en_US.UTF-8 growpart /dev/$top_disk_name $disk_number
    fi

    disk_filesystem_type=$(df -Th | grep $(echo "$var" | sed 's/\/dev\///g' | sed 's/\//-/g') | awk '{print $2}')
    pvresize /dev/$disk_name
    lvextend -l +100%FREE $var
else
    disk_filesystem_type=$(df -Th | grep $disk_name | awk '{print $2}')
    if [[ "$disk_type" != "raw" ]]; then
        LC_ALL=en_US.UTF-8 growpart /dev/$top_disk_name $disk_number
    fi
fi

# Determine if it is an XFS or EXT file system
if [[ "$disk_filesystem_type" == "xfs" && -n "$var" ]]; then
    xfs_growfs $var
elif [ "$disk_filesystem_type" == "xfs" ]; then
    xfs_growfs /dev/$disk_name
elif [[ $(echo $disk_filesystem_type | grep ext | wc -l) -eq 1 && -n "$var" ]]; then
    resize2fs $var
elif [ $(echo $disk_filesystem_type | grep ext | wc -l) -eq 1 ]; then
    resize2fs /dev/$disk_name
fi

if [ $? -eq 0 ];then
    echo -e "\033[32mDisk expansion successful\033[0m"
fi
exit 0
END
本文作者:
文章标题: 使用Shell自动进行分区扩容,支持CentOS和Ubuntu系统
本文地址: https://blog.imwlw.com/archives/29/
版权说明:若无注明,本文皆 ITShare Studio 原创,转载请保留文章出处。
最后修改:2025 年 01 月 24 日
如果觉得我的文章对你有用,请随意赞赏