注册
逻辑卷分区挂盘脚本
技术分享/ 文章详情 /

逻辑卷分区挂盘脚本

竹蜻蜓vYv 2023/04/17 1881 12 0

1.脚本内容

#!/bin/bash #==============================================================# # 脚本名 : create_lvm.sh # 创建时间 : 2023-04-17 10:02:09 # 更新时间 : 2023-04-17 18:12:18 # 描述 : 创建逻辑卷脚本 # 路径 : /soft/create_lvm.sh # 版本 : 1.0.0 # 作者 : yuanzijian(yzj@dameng.com) # Copyright (C) 2023-2023 Zijian yuan #==============================================================# #输入环境变量 export PATH=$PATH:/sbin:/usr/sbin #获取当前系统版本 os_version=$(grep -oP '(?<=release\s|V)[[:digit:]]+' </etc/system-release) #传入的磁盘 typeset -l disk_list= #卷组名称 typeset -l vg_name= #逻辑卷名称 typeset -l lv_name= #定义逻辑卷数组 declare -a lv_names=() #逻辑卷的大小 input_size= #是百分比还是具体值 typeset -u is_value_percent=Y # 定义全局变量,退出函数的标记 flag="" # 定义磁盘挂载点 typeset -l mount_dir= # 定义 run_command 函数 function run_command() { "$@" >/dev/null 2>&1 # 执行传入的命令和参数 local status=$? # 获取命令的退出状态 if [ $status -eq 0 ]; then # 如果命令执行成功 echo -e "\n命令\033[32m \"$*\" \033[0m执行成功。" return 0 # 返回 0,使得当前命令退出 else # 如果命令执行失败 echo -e "\n命令\033[31m \"$*\" \033[0m执行失败,退出码为 $status。\n" return $status # 返回命令的退出状态,使得当前命令继续执行 fi } function confirm_command() { local command1=$1 local command2=$2 local command3=$3 local flag="" while true; do # 用户决定是否创建 read -r -p "请确认是否创建,确认输入[Y]/重新配置输入[N],退出输入[Q] " -e choice case "$choice" in [Yy]) # 执行命令 run_command $command1 break ;; [Nn]) $command2 break ;; [Qq]) flag="exit" break ;; *) echo -e "\n请输入 Y、N 或者 Q.\n" ;; esac done # 判断是否需要继续创建逻辑卷 if [[ "$flag" == "exit" ]]; then $command3 fi } # 校验磁盘是否存在 function check_disks() { local input_disks="$1" #定义符合要求磁盘数组名称 local valid_disks=() #定义不符合要求磁盘数组名称 local invalid_disks=() for disk in ${input_disks// / }; do # Check if the disk exists if [[ -b $disk ]]; then valid_disks+=("$disk") else invalid_disks+=("$disk") fi done # Check if all disks are valid if [[ ${#invalid_disks[@]} -eq 0 ]]; then echo -e "\n输入的磁盘列表为:\033[32m ${valid_disks[*]} \033[0m\n" return 0 else echo -e "\n磁盘:\033[31m ${invalid_disks[*]} \033[0m名称无效\n" return 1 fi } # 校验数值是否为正整数 function check_disk_size() { input_size=$1 while true; do if ! [[ $input_size =~ ^[0-9]+$ ]]; then echo -e "\n\033[31m无效的输入,请输入一个正整数。\033[0m\n" read -r -e input_size continue else echo -e "\n输入的数据大小为:\033[32m $input_size \033[0m\n" return 0 fi done return 1 } #判断校验卷组名字是否只包含字母和数字 function check_alphanumeric() { # 循环遍历字符串中的每个字符 for ((i = 0; i < ${#1}; i++)); do char="${1:$i:1}" # 如果字符不是字母或数字,返回1 if [[ ! "$char" =~ [[:alnum:]] ]]; then return 1 fi done # 判断字符串是否全部由数字组成 if [[ -z "$1" ]]; then return 1 elif [[ "$1" =~ ^[0-9]*$ ]]; then return 1 else return 0 fi } # 校验目录是否已经挂载 function check_mount_dir() { mount_dir=$1 while true; do if [[ "${mount_dir}" =~ ^/ ]]; then if [[ "$mount_dir" == "/" ]] || grep -qs "$mount_dir " /proc/mounts; then echo -e "\n\033[31m目录已经被挂载,请重新输入要挂载的目录名。\033[0m\n" read -r -e mount_dir continue else echo -e "\n要挂载的目录名:\033[32m $mount_dir \033[0m" break fi else echo -e "\n\033[31m目录名不是以/开头,请重新输入要挂载的目录名。\033[0m\n" read -r -e mount_dir continue fi done } function create_pvs() { # 校验磁盘 while true; do # 获取用户输入的磁盘名 echo -e "\n请输入磁盘名(例如 /dev/sdb或者/dev/sdb /dev/sdc):\n" read -r -e disk_list check_disks "$disk_list" # 判断函数执行结果 if [[ $? -eq 0 ]]; then echo -e "校验磁盘成功\n" break else echo -e "\033[31m校验磁盘失败,请重新输入\033[0m\n" continue fi done # 创建物理卷 confirm_command "pvcreate -y -ff $disk_list" "create_pvs" "exit 0" } function create_vgs() { while true; do # 获取用户输入的卷组名称 echo -e "\n请输入卷组名称(可以包含数字):\n" read -r -e vg_name check_alphanumeric "$vg_name" # 判断函数执行结果 if [[ $? -eq 0 ]]; then echo -e "\n输入卷组名称符合要求\n" break else echo -e "\n\033[31m输入卷组名称不符合要求,请重新输入\033[0m\n" continue fi done # 创建卷组 confirm_command "vgcreate -y $vg_name $disk_list" "create_vgs" "exit 0" } function create_lvs() { # 建逻辑卷的方法 local lv_method= # 判断是否需要继续创建逻辑卷 if [[ "$flag" == "exit" ]]; then # 退出整个函数 return fi # 校验传入的逻辑卷大小 while true; do # 获取用户输入的逻辑卷名称 echo -e "\n请输入逻辑卷名称(可以包含数字):\n" read -r -e lv_name check_alphanumeric "$lv_name" # 判断函数执行结果 if [[ $? -eq 0 ]]; then echo -e "\n输入逻辑名称符合要求" break else echo -e "\n\033[31m输入逻辑名称不符合要求,请重新输入\033[0m" continue fi done # 校验传入的逻辑卷大小 while true; do # 检查卷组剩余空间大小 free=$(vgs | grep "$vg_name" | awk '{print $7}') echo -e "\n该卷组剩余的空间大小为:\033[32m$free\033[0m" # 获取用户输入的数据大小 echo -e "\n请输入数据大小(例如 10 ):\n" read -r -e input_size check_disk_size "$input_size" # 判断函数执行结果 if [[ $? -eq 0 ]]; then echo -e "校验数据大小成功\n" break else echo -e "\033[31m校验数据大小失败,请重新输入\033[0m\n" continue fi done #创建逻辑卷参数方式 if [[ $is_value_percent == "Y" ]]; then lv_method="-l +${input_size}%VG" else lv_method="-L +${input_size}G" fi while true; do # 用户决定是否创建 read -r -p "请确认是否创建,确认输入[Y]/重新配置输入[N],退出输入[Q] " -e choice case "$choice" in [Yy]) # 执行命令 run_command lvcreate -y $lv_method -n $lv_name $vg_name break ;; [Nn]) return 4 ;; [Qq]) flag="exit" break ;; *) echo -e "\n请输入 Y、N 或者 Q.\n" ;; esac done # 如果逻辑卷创建成功,创建的逻辑卷加到数组里面 if lvs --noheadings -o lv_name --select "vg_name=$vg_name" | grep -qw "$lv_name"; then # 判断逻辑卷名称是否已经存在于数组中 exists=0 for i in "${lv_names[@]}"; do if [ "$i" == "$lv_name" ]; then exists=1 break fi done if [[ "$exists" -eq 0 ]]; then # 将逻辑卷名称添加到数组中 lv_names+=("$lv_name") fi fi while true; do # 继续循环创建逻辑卷 echo read -r -p "是否继续创建逻辑卷?[Y/N] " -e choice case "$choice" in [Yy]) echo -e "\n您选择了继续创建。" return 4 ;; [Nn]) echo -e "\n您选择了退出创建。" flag="exit" break ;; *) echo -e "\n\033[31m输入有误,请重新输入。\033[0m" ;; esac done } # 格式化逻辑卷,并挂盘 function format_and_mount_lvms() { #格式化文件类型 local fst= # 挂载点路径 local mount_dir= # 根据系统选择格式化的文件类型 case $os_version in 6) fst=ext4 ;; 7 | 8 | 9 | 10) fst=xfs ;; *) fst=xfs ;; esac echo -e "\n格式化文件系统类型为:\033[32m $fst \033[0m" # 格式化文件类型 for lv_name in "${lv_names[@]}"; do run_command mkfs.$fst -f /dev/mapper/"$vg_name"-"$lv_name" done # 创建挂载点,挂载目录 while true; do # 获取用户输入的挂载点目录 local mount_dir="" declare -A mount_point=() for lv_name in "${lv_names[@]}"; do echo -e "\n请输入逻辑卷\033[32m /dev/mapper/$vg_name-$lv_name\033[0m 挂载目录(例如\033[32m /$lv_name \033[0m ):\n" read -r -e mount_dir # 校验挂载目录 if check_mount_dir "$mount_dir"; then run_command mkdir -p $mount_dir mount_point+=([$lv_name]=${mount_dir%/}) fi done # 创建挂载点并挂载逻辑卷 for lv_name in "${lv_names[@]}"; do # 编写fstab文件 fstab_entry="/dev/mapper/$vg_name-$lv_name ${mount_point[$lv_name]} $fst defaults 0 0" if grep -qF "/dev/mapper/$vg_name-$lv_name" /etc/fstab; then sed -i "/^\/dev\/mapper\/$vg_name-$lv_name/c$fstab_entry"/etc/fstab else echo "$fstab_entry" >>/etc/fstab fi mount -a echo -e "\n已成功挂载分区\033[32m /dev/mapper/$vg_name-$lv_name\033[0m 到\033[32m ${mount_point[$lv_name]} \033[0m 目录下。" done if [[ $? -eq 0 ]]; then echo -e "\n逻辑卷创建成功,请查验:\n" break else echo -e "\n\033[31m逻辑卷创建失败,请手动删除,重新配置\033[0m" continue fi done df -Th echo } function confirm_lv_configuration() { # 确认创建逻辑卷的方式,是按照百分比还是按照真实值 cat <<EOF 请确认创建逻辑卷方式: 1 百分比 2 具体值(单位是:G) EOF while true; do read -r -p "请选择逻辑卷创建方式:" -e confirm case $confirm in 1) is_value_percent=Y break ;; 2) is_value_percent=N break ;; *) echo "请输入 1 或者 2 。" ;; esac done # 创建物理卷 create_pvs # 创建卷组 create_vgs # 创建逻辑卷 create_lvs while [ "$?" -eq "4" ]; do create_lvs #如果返回值是4,就一直执行create_lvs函数 done # 格式化逻辑卷,并挂盘 format_and_mount_lvms } confirm_lv_configuration

2.脚本使用方法

1.png2.png3.png4.png

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服