一.前置条件
在要使用Shell脚本实现LVM分区,你需要先确保系统中已经安装了LVM工具。可以执行lvm version
检查系统是否安装了lvm工具
二.运行环境
脚本适用于所有linux发行版,例如ubuntu、centos…等系统
三 .功能描述
3.1 lvm分区示意图
3.2 脚本实现的功能
- 创建分区:对物理磁盘进行分区规划
- 创建PV:将创建的分区做成PV卷
- 创建VG:将PV合并成VG卷组
- 创建LV:从VG卷组中分配空间形成LV卷
- 格式化LV:将LV卷格式化为linux可用的文件格式
- 挂载分区:将文件系统挂载到相应LV分区
四.程序设计
4.1 设计思路
程序采用模块化设计,每一个函数实现一个功能点,程序在执行过程中有友好的提示交互,用户输入变量值,每一个关键的步骤程序都会输出结果。程序最大的亮点是考虑到了各类情况,不能保证100%完美,但基本能处理90%的异常,非常适合小白使用!!
4.2 功能点实现
4.2.1 主程序
#!/bin/bash
Red='\033[0;31m'
Blue='\033[0;34m'
Green='\033[0;32m'
Color_Off='\033[0m'
if [ "$LOGNAME" != "root" ];then
echo -e "$Red当前非root用户,请切换至root用户再执行脚本.$Color_Off"
exit 1
fi
echo -e "$Blue确保你已备份数据,并且知道你正在做什么.按任意键继续或者Ctrl+C取消$Color_Off"
read -n 1 -s
PS3="请输入您的选择:"
while true
do
echo "================================================================="
select choice in "磁盘分区" "创建PV卷" "创建VG卷" "创建LV卷" "格式化分区" "创建挂载" "退出";do
case $choice in
"磁盘分区")
create_partition
break
;;
"创建PV卷")
create_pv
break
;;
"创建VG卷")
create_vg
break
;;
"创建LV卷")
create_lv
break
;;
"格式化分区")
filesystem_format
break
;;
"创建挂载")
filesystem_mount
break
;;
"退出")
exit 1
;;
*)
echo -e "$Blue无效的选择,请重新选择!!$Color_Off"
break
esac
done
done
效果展示:
4.2.2 创建分区
create_partition(){
read -p "请输入你要分区的磁盘(eg:/dev/sdb):" DISK
if [ ! -e $DISK ];then
echo -e "$Red您输入的设备$DISK不存在.$Color_Off"
#exit
return 1
fi
read -p "请为$DISK规划标准分区的数量(eg:1,2,3,4...),默认1个:" NUMS
for NUM in `seq 1 $NUMS`
do
echo -e "$Blue开始做第$NUM个分区$Color_Off"
read -p "请输入要创建的分区类型(这里只能是主分区,默认按回车即可):" A
read -p "请输入分区数字,从1开始,自动编号,默认按回车即可:" B
read -p "请输入扇区起始表号,默认按回车即可:" C
read -p "请输入分区大小(如+5G),默认为磁盘可用最大容量:" D
fdisk $DISK > create_partiton.log 2>&1 << EOF
n
p
$B
$C
$D
w
EOF
if grep -q "Value out of range" create_partiton.log;then
echo -e "$Red磁盘空间不足,第$NUM个标准linux分区创建失败,程序退出!!$Color_Off"
rm -rf create_partiton.log
return 1
#exit
else
echo -e "$Green第$NUM个标准linux分区创建好了!!$Color_Off"
fi
done
rf -rf create_partiton.log
echo -e "$Green恭喜你,所有分区都创建好了!!$Color_Off"
}
4.2.3 创建PV
create_pv(){
read -p "请输入需要创建成PV的分区名称,多个用逗号分隔(eg:sdb1,sdb2):" PV_DEVICE
pv_array=(${PV_DEVICE//,/ })
for pv in ${pv_array[@]}
do
if [ -b /dev/$pv ];then
pvcreate /dev/$pv
else
echo -e "$Red$pv分区不存在,创建pv失败!!$Color_Off"
continue
fi
done
}
4.2.4 创建VG
create_vg(){
read -p "请输入要创建几个VG卷组(eg:1,2...):" I
for i in `seq 1 $I`
do
read -p "请给为要创建的第$i个VG卷起一个名称:(eg:vg0):" VG_NAME
read -p "请输入要将哪些PV加入$VG_NAME,多个用空格分隔:(eg:sdb1 sdb2):" VG_DEVICE
VG_DISK=
for vg_device in $VG_DEVICE
do
if [ -b /dev/$vg_device ];then
VG_DISK="$VG_DISK /dev/$vg_device"
else
echo -e "${Red}pv-$vg_device不存在,创建$VG_NAME卷组失败!!$Color_Off"
break
fi
done
if [ "$VG_DISK" = '' ];then
continue
fi
vgcreate $VG_NAME $VG_DISK
if [ $? -ne 0 ];then
echo -e "$Red创建$VG_NAME失败!!$Color_Off"
fi
done
}
4.2.5 创建LV
create_lv(){
read -p "请你输入要创建逻辑卷的个数(eg:1,2...),默认创建一个:" LV_NUMS
for num in `seq 1 $LV_NUMS`
do
read -p "请输入分配LV容量的VG卷组名称:" VG_NAME
read -p "请输入要创建第$num个LV的名称(eg:lv_1):" LV_NAME
read -p "请指定$LV_NAME的大小:(eg:500M,10G):" LV_SIZE
if vgs | grep -q $VG_NAME; then
lvcreate -L $LV_SIZE -n $LV_NAME $VG_NAME
if [ $? -ne 0 ]; then
free_pe=`vgdisplay vg0 |grep 'Free'|awk -F / '{print $2}'|awk '{ print $2}'`
if [ $free_pe -eq 0 ];then
echo -e "${Red}${VG_NAME}可用PE数为0,无法再创建LV!!${Color_Off}"
return 1
fi
echo -e "$Bule$VG_NAME可用PE个数为:$free_pe$Color_Off"
read -p "请输入有效PE数重新创建LV:" PE_NUM
lvcreate -l $PE_NUM -n $LV_NAME $VG_NAME
fi
else
echo -e "$Red$VG_NAME卷组不存在,创建第LV逻辑卷失败!!$Color_Off"
break
fi
done
}
4.2.6 格式化分区
filesystem_format(){
while true
do
read -p "请输入需要格式化的设备(eg:/dev/vg0/lv1):" DEVICE_FORMAT
if [ -b $DEVICE_FORMAT ];then
read -p "请确认$DEVICE_FORMAT要格式化的文件系统类型(ext4,xfs):" FILE_SYSTEM
if [ "$FILE_SYSTEM" = "ext4" ];then
mkfs.ext4 $DEVICE_FORMAT <<< 'y'
echo -e "${Green}${DEVICE_FORMAT}设备已格式化为ext4${Color_Off}"
elif [ "$FILE_SYSTEM" = "xfs" ];then
mkfs.xfs -f $DEVICE_FORMAT
echo -e "${Green}${DEVICE_FORMAT}设备已格式化为xfs${Color_Off}"
else
echo -e "${Red}${DEVICE_FORMAT}设备格式化失败!!${Color_Off}"
fi
else
echo -e "$Red输入的$DEVICE_FORMAT设备不存在,无法格式化!!$Color_Off"
fi
read -p "输入q退出程序,输入其他程序继续...:" input
if [ "$input" = "q" ];then
break
else
continue
fi
done
}
4.2.7 挂载分区
filesystem_mount(){
while true;do
read -p "请输入要挂载的设备:(eg:/dev/vg0/lv1):" MOUNT_DEVICE
if [ ! -b $MOUNT_DEVICE ] || [ "$MOUNT_DEVICE" = "" ];then
echo -e "${Red}${MOUNT_DEVICE}设备不存在,无法挂载!!${Color_Off}"
read -p "输入q退出程序,输入其他程序继续...:" input
if [ "$input" = "q" ];then
break
else
continue
fi
fi
read -p "请输入$MOUNT_DEVICE设备的挂载点(eg:/mnt):" MOUNT_POINT
if [ ! -d "$MOUNT_POINT" ] && [ ! -z "$MOUNT_POINT" ]; then
mkdir -p $MOUNT_POINT
fi
file_format=`lsblk -f $MOUNT_DEVICE |awk 'NR==2 {print $2}'`
find_fstab=`cat /etc/fstab|grep "$MOUNT_DEVICE"|awk -F'/' '{print $4}'`
if [ -z "$find_fstab" ];then
echo "$MOUNT_DEVICE $MOUNT_POINT $file_format defaults 0 0" >> /etc/fstab
echo -e "${Blue}${MOUNT_DEVICE} $MOUNT_POINT新写入/etc/fstab文件中$Color_Off"
else
sed -ri "/$find_fstab/c$MOUNT_DEVICE $MOUNT_POINT $file_format defaults 0 0" /etc/fstab
echo -e "${Blue}${MOUNT_DEVICE} $MOUNT_POINT已替换原来的内容$Color_Off"
fi
read -p "输入q退出程序,输入其他程序继续...:" input
if [ "$input" = "q" ];then
break
else
continue
fi
done
systemctl daemon-reload && mount -a && echo -e "$Green文件挂载成功并已持久化挂载!!$Color_Off"
}
五.总结
程序目前只是完成了创建LVM主体流程,还可能添加更多的功能模块,比如一些查看,删除的操作。欢迎各位博友使用,并指出优化意见!!
附完整代码
#!/bin/bash
Red='\033[0;31m'
Blue='\033[0;34m'
Green='\033[0;32m'
Color_Off='\033[0m'
create_partition(){
read -p "请输入你要分区的磁盘(eg:/dev/sdb):" DISK
if [ ! -e $DISK ];then
echo -e "$Red您输入的设备$DISK不存在.$Color_Off"
#exit
return 1
fi
read -p "请为$DISK规划标准分区的数量(eg:1,2,3,4...),默认1个:" NUMS
for NUM in `seq 1 $NUMS`
do
echo -e "$Blue开始做第$NUM个分区$Color_Off"
read -p "请输入要创建的分区类型(这里只能是主分区,默认按回车即可):" A
read -p "请输入分区数字,从1开始,自动编号,默认按回车即可:" B
read -p "请输入扇区起始表号,默认按回车即可:" C
read -p "请输入分区大小(如+5G),默认为磁盘可用最大容量:" D
fdisk $DISK > create_partiton.log 2>&1 << EOF
n
p
$B
$C
$D
w
EOF
if grep -q "Value out of range" create_partiton.log;then
echo -e "$Red磁盘空间不足,第$NUM个标准linux分区创建失败,程序退出!!$Color_Off"
rm -rf create_partiton.log
return 1
#exit
else
echo -e "$Green第$NUM个标准linux分区创建好了!!$Color_Off"
fi
done
rf -rf create_partiton.log
echo -e "$Green恭喜你,所有分区都创建好了!!$Color_Off"
}
create_pv(){
read -p "请输入需要创建成PV的分区名称,多个用逗号分隔(eg:sdb1,sdb2):" PV_DEVICE
pv_array=(${PV_DEVICE//,/ })
for pv in ${pv_array[@]}
do
if [ -b /dev/$pv ];then
pvcreate /dev/$pv
else
echo -e "$Red$pv分区不存在,创建pv失败!!$Color_Off"
continue
fi
done
}
create_vg(){
read -p "请输入要创建几个VG卷组(eg:1,2...):" I
for i in `seq 1 $I`
do
read -p "请给为要创建的第$i个VG卷起一个名称:(eg:vg0):" VG_NAME
read -p "请输入要将哪些PV加入$VG_NAME,多个用空格分隔:(eg:sdb1 sdb2):" VG_DEVICE
VG_DISK=
for vg_device in $VG_DEVICE
do
if [ -b /dev/$vg_device ];then
VG_DISK="$VG_DISK /dev/$vg_device"
else
echo -e "${Red}pv-$vg_device不存在,创建$VG_NAME卷组失败!!$Color_Off"
break
fi
done
if [ "$VG_DISK" = '' ];then
continue
fi
vgcreate $VG_NAME $VG_DISK
if [ $? -ne 0 ];then
echo -e "$Red创建$VG_NAME失败!!$Color_Off"
fi
done
}
create_lv(){
read -p "请你输入要创建逻辑卷的个数(eg:1,2...),默认创建一个:" LV_NUMS
for num in `seq 1 $LV_NUMS`
do
read -p "请输入分配LV容量的VG卷组名称:" VG_NAME
read -p "请输入要创建第$num个LV的名称(eg:lv_1):" LV_NAME
read -p "请指定$LV_NAME的大小:(eg:500M,10G):" LV_SIZE
if vgs | grep -q $VG_NAME; then
lvcreate -L $LV_SIZE -n $LV_NAME $VG_NAME
if [ $? -ne 0 ]; then
free_pe=`vgdisplay vg0 |grep 'Free'|awk -F / '{print $2}'|awk '{ print $2}'`
if [ $free_pe -eq 0 ];then
echo -e "${Red}${VG_NAME}可用PE数为0,无法再创建LV!!${Color_Off}"
return 1
fi
echo -e "$Bule$VG_NAME可用PE个数为:$free_pe$Color_Off"
read -p "请输入有效PE数重新创建LV:" PE_NUM
lvcreate -l $PE_NUM -n $LV_NAME $VG_NAME
fi
else
echo -e "$Red$VG_NAME卷组不存在,创建第LV逻辑卷失败!!$Color_Off"
break
fi
done
}
filesystem_format(){
while true
do
read -p "请输入需要格式化的设备(eg:/dev/vg0/lv1):" DEVICE_FORMAT
if [ -b $DEVICE_FORMAT ];then
read -p "请确认$DEVICE_FORMAT要格式化的文件系统类型(ext4,xfs):" FILE_SYSTEM
if [ "$FILE_SYSTEM" = "ext4" ];then
mkfs.ext4 $DEVICE_FORMAT <<< 'y'
echo -e "${Green}${DEVICE_FORMAT}设备已格式化为ext4${Color_Off}"
elif [ "$FILE_SYSTEM" = "xfs" ];then
mkfs.xfs -f $DEVICE_FORMAT
echo -e "${Green}${DEVICE_FORMAT}设备已格式化为xfs${Color_Off}"
else
echo -e "${Red}${DEVICE_FORMAT}设备格式化失败!!${Color_Off}"
fi
else
echo -e "$Red输入的$DEVICE_FORMAT设备不存在,无法格式化!!$Color_Off"
fi
read -p "输入q退出程序,输入其他程序继续...:" input
if [ "$input" = "q" ];then
break
else
continue
fi
done
}
filesystem_mount(){
while true;do
read -p "请输入要挂载的设备:(eg:/dev/vg0/lv1):" MOUNT_DEVICE
if [ ! -b $MOUNT_DEVICE ] || [ "$MOUNT_DEVICE" = "" ];then
echo -e "${Red}${MOUNT_DEVICE}设备不存在,无法挂载!!${Color_Off}"
read -p "输入q退出程序,输入其他程序继续...:" input
if [ "$input" = "q" ];then
break
else
continue
fi
fi
read -p "请输入$MOUNT_DEVICE设备的挂载点(eg:/mnt):" MOUNT_POINT
if [ ! -d "$MOUNT_POINT" ] && [ ! -z "$MOUNT_POINT" ]; then
mkdir -p $MOUNT_POINT
fi
file_format=`lsblk -f $MOUNT_DEVICE |awk 'NR==2 {print $2}'`
find_fstab=`cat /etc/fstab|grep "$MOUNT_DEVICE"|awk -F'/' '{print $4}'`
if [ -z "$find_fstab" ];then
echo "$MOUNT_DEVICE $MOUNT_POINT $file_format defaults 0 0" >> /etc/fstab
echo -e "${Blue}${MOUNT_DEVICE} $MOUNT_POINT新写入/etc/fstab文件中$Color_Off"
else
sed -ri "/$find_fstab/c$MOUNT_DEVICE $MOUNT_POINT $file_format defaults 0 0" /etc/fstab
echo -e "${Blue}${MOUNT_DEVICE} $MOUNT_POINT已替换原来的内容$Color_Off"
fi
read -p "输入q退出程序,输入其他程序继续...:" input
if [ "$input" = "q" ];then
break
else
continue
fi
done
systemctl daemon-reload && mount -a && echo -e "$Green文件挂载成功并已持久化挂载!!$Color_Off"
}
if [ "$LOGNAME" != "root" ];then
echo -e "$Red当前非root用户,请切换至root用户再执行脚本.$Color_Off"
exit 1
fi
echo -e "$Blue确保你已备份数据,并且知道你正在做什么.按任意键继续或者Ctrl+C取消$Color_Off"
read -n 1 -s
PS3="请输入您的选择:"
while true
do
echo "================================================================="
select choice in "磁盘分区" "创建PV卷" "创建VG卷" "创建LV卷" "格式化分区" "创建挂载" "退出";do
case $choice in
"磁盘分区")
create_partition
break
;;
"创建PV卷")
create_pv
break
;;
"创建VG卷")
create_vg
break
;;
"创建LV卷")
create_lv
break
;;
"格式化分区")
filesystem_format
break
;;
"创建挂载")
filesystem_mount
break
;;
"退出")
exit 1
;;
*)
echo -e "$Blue无效的选择,请重新选择!!$Color_Off"
break
esac
done
done