shell分支语句

if

if关键字可以进行脚本的分支判断,控制程序的执行过程,与C不同,它不是以花括号{}来区分作用域;if通过一个反写的fi来限定代码作用域的,如下:

#为了使代码结构清晰,使用了缩进,不添加缩进语句也是可以被正常解析执行的
if [ "$HOSTNAME" = "shell" ]
then
	echo "yes"
else
	else echo "no"
fi
#写在一行时需要使用分号表示语句末尾,否则报语法错误
if [ "$HOSTNAME" = "shell" ]; then echo "yes"; else echo "no"; fi
#我通常使用下面的写法,没办法,学C后遗留的强迫症😂
if [ "$HOSTNAME" = "shell" ]; then
	echo "yes"
else
	echo "no"
fi

if也可以使用elif进行多条件判断,也可以叫做嵌套,如下:

#多级if写法
if [ 表达式1 ]; then
	command
elif [ 表达式2 ]; then
	command
elif [ 表达式3 ]; then
	command
else
	command
fi

case

若存在嵌套过多的if语句时,可根据要实现的具体功能和流程来选择使用case语句,它类似于C中的switch语句,可有效降低代码的复杂度,增加代码的可读性,语法如下:

#case语句与if一样使用反写的形式限定代码块
#使用缩进仅仅是为了提高代码可读性
#;;表示跳出,像break
#1)匹配的值
#*)匹配所有,如果*)之前的都没匹配上,则执行*)处的定义
#任意条件匹配,代码执行到;;都会退出该case
case $var in
1)
	command1
	;;
2)
	command2
	;;
3)
	command3
	;;
*)
	default_command
	;;
esac
#下面的写法也可以
case $var in
	1)	command1
		;;
	2)	command2
		;;
	3)	command3
		;;
	*)	default_command
		;;
esac

扩展:

  1. 根据操作系统的版本号更换不同的仓库

    #!/bin/bash
    #Author:     zhuyongci.com
    #Date:          2019/08/03
    #Version:             v1.5
    
    #该脚本在CentOS6.9和CentOS7 1810全新环境下均测试执行成功,可以正常使用
    #如果yum makechche阶段很慢,则将其注释即可,脚本可优化的地方还有很多
    
    #支持的系统如下
    support_os=("CentOS 6" "CentOS 7")
    
    #取系统版本号,从文件行尾取,然后保留主版本号
    os_ver=$(awk '{print $(NF-1)}' /etc/redhat-release | cut -c1)
    
    #repo目录及文件定义
    repo_dir="/etc/yum.repos.d"
    repo_base_name="Tsinghua-Base.repo"
    repo_epel_name="Tsinghua-Epel.repo"
    
    #CentOS6 Base源文件内容定义
    mirrors_base_6="[base]\nname=CentOS-\$releasever - Base\nbaseurl=https://mirrors.tuna.tsinghua.edu.cn/centos/\$releasever/os/\$basearch/\n#mirrorlist=http://mirrorlist.centos.org/?release=\$releasever&arch=\$basearch&repo=os\ngpgcheck=1\ngpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6\n"
    
    #CentOS6 epel-release包定义
    epel6_release_uri="https://mirrors.tuna.tsinghua.edu.cn/epel/epel-release-latest-6.noarch.rpm"
    #CentOS6 Epel源文件内容定义
    mirrors_epel_6="[epel]\nname=Extra Packages for Enterprise Linux 6 - \$basearch\nbaseurl=https://mirrors.tuna.tsinghua.edu.cn/epel/6/\$basearch\n#mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=\$basearch\nfailovermethod=priority\nenabled=1\ngpgcheck=1\ngpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6\n"
    
    #CentOS7 Base源文件内容定义
    mirrors_base_7="[base]\nname=CentOS-\$releasever - Base\nbaseurl=https://mirrors.tuna.tsinghua.edu.cn/centos/\$releasever/os/\$basearch/\n#mirrorlist=http://mirrorlist.centos.org/?release=\$releasever&arch=\$basearch&repo=os\ngpgcheck=1\ngpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7\n"
    
    #CentOS7 epel-release包定义
    epel7_release_uri="https://mirrors.tuna.tsinghua.edu.cn/epel/epel-release-latest-7.noarch.rpm"
    #CentOS7 Epel源文件内容定义
    mirrors_epel_7="[epel]\nname=Extra Packages for Enterprise Linux 7 - \$basearch\nbaseurl=https://mirrors.tuna.tsinghua.edu.cn/epel/7/\$basearch\n#mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-7&arch=\$basearch\nfailovermethod=priority\nenabled=1\ngpgcheck=1\ngpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7\n"
    
    #自定义println命令,如果系统存在function函数库,则导入该库,如果不存在该库则使用自定义的显示风格
    #该变量用于存储判断结果,若系统中存在functions函数库则为0,否则该变量被置1
    export func_state=0
    [ -f /etc/init.d/functions ] && . /etc/init.d/functions || func_state=1
    #判断func_state,如果不等于0则使用println的另一套定义,等于0则直接调用action
    if [ $func_state -eq 0 ]; then
            println() {
            action "${1}" "${2}"
            }
    else
            println() {
                    if [ $2 = "/bin/true" ]; then
                            echo -e "[  \033[32mOK\033[0m  ]    $1"
                    else
                            echo -e "[\033[31mFAILED\033[0m]    $1"
                    fi
            }
    fi
    
    #检查网络连接
    #提示信息
    echo -e "\033[33m\033[5m检测网络连接中,请等待...\033[0m"
    #C6使用脚本重启网络服务
    c6_network_restart="/etc/init.d/network restart"
    #c7使用systemd重启网络服务
    c7_network_restart="systemctl restart network"
    	#先检查下,没啥问题就跳过了,如果网络不通就尝试重启网络服务
    ping -c2 -W2 www.baidu.com &> /dev/null
    if [ $? -ne 0 ]; then
    	[ $os_ver -eq 6 ] && $c6_network_restart || $c7_network_restart
    	if [ $? -ne 0 ]; then
    		println "尝试重启网络服务失败!\a" /bin/false
    		exit 1
    	else
    		ping -c2 -W2 www.qq.com &> /dev/null
    		if [ $? -ne 0 ]; then
    			println "已尝试重启网络服务,但依旧无法上网!" /bin/false
    			exit 1
    		fi
    	fi
    else
    	println "检查网络连接成功..." "/bin/true"
    fi
    
    #打印提示信息
    echo -e "\033[33m开始为系统更换软件仓库.\033[0m"
    
    #更换Base源
    if [ $os_ver -eq 6 ]; then
    	[ -f $repo_dir/*Base.repo ] && gzip $repo_dir/*Base.repo &> /dev/null
    	echo -e "$mirrors_base_6" > $repo_dir/$repo_base_name
    	yum clean all && yum makecache
    	println "软件仓库更换成功!已更换为: ${repo_base_name} 的源." "/bin/true"
    elif [ $os_ver -eq 7 ]; then
    	[ -f $repo_dir/*Base.repo ] && gzip $repo_dir/*Base.repo &> /dev/null
    	echo -e "$mirrors_base_7" > $repo_dir/$repo_base_name
    	yum clean all && yum makecache
    	println "软件仓库更换成功!已更换为: ${repo_base_name} 的源." "/bin/true"
    else
    	println "更换软件仓库失败!请检查系统是否为所支持的版本!" "/bin/false"
    	echo "本脚本仅支持以下系统:"
    	#遍历support_os数组,数组元素从0开始,所以要先减1
    	for i in `seq 0 $[${#support_os[*]}-1]`; do
    		echo -e "\033[32m${support_os[${i}]}\033[0m"
    	done
    	exit 1
    fi
    
    #更换Epel源
    #对于CentOS 6来说,必须先安装yum-priorities优先级插件
    #然后安装epel-release包,否则必须手动关闭GPG-KEY的检查或者手动导入GPG-KEY
    #CentOS 6最后一个可用的epel-release
    
    if [ $os_ver -eq 6 ]; then
    	#先安装必须的包
    	yum install yum-priorities -y
    	if [ $? -ne 0 ]; then
    		println "yum-priorities插件安装失败!" "/bin/false"
    		exit 1
    	else
    		yum install $epel6_release_uri -y
    		if [ $? -ne 0 ]; then
    			println "epel-release包安装失败!请检查是否是已安装或资源已失效!" "/bin/false"
    			exit 1
    		fi
    		#导入GPG-KEY
    		rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6
    		#备份默认的epel仓库
    		[ -f $repo_dir/epel.repo ] && gzip $repo_dir/epel*.repo &> /dev/null
    		#创建新的epel.repo文件
    		echo -e "$mirrors_epel_6" > $repo_dir/$repo_epel_name
    		yum clean all && yum makecache
    		println "软件仓库更换成功!已更换为: ${repo_epel_name} 的源." "/bin/true"
    	fi
    elif [ $os_ver -eq 7 ]; then
    	yum install $epel7_release_uri -y
    	if [ $? -ne 0 ]; then
    		println "epel-release包安装失败!请检查是否是已安装或资源已失效!" "/bin/false"
    		exit 1
    	fi
    	#导入GPG-KEY
    	rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
    	#备份默认的epel仓库
    	[ -f $repo_dir/epel.repo ] && gzip $repo_dir/epel*.repo &> /dev/null
    	#创建新的epel.repo文件
    	echo -e "$mirrors_epel_7" > $repo_dir/$repo_epel_name
    	yum clean all && yum makecache
    	println "软件仓库更换成功!已更换为: ${repo_epel_name} 的源." "/bin/true"
    else
    	println "更换软件仓库失败!请检查系统是否为所支持的版本!" "/bin/false"
    	echo "本脚本仅支持以下系统:"
    	#遍历support_os数组,数组元素从0开始,所以要先减1
    	for i in `seq 0 $[${#support_os[*]}-1]`; do
    		echo -e "\033[32m${support_os[${i}]}\033[0m"
    	done
    	exit 1
    fi
    
    unset func_state
    
  2. 猜数字游戏,使用了系统环境变量$RANDOM

    #!/bin/bash
    
    rand=$(echo $(($RANDOM%100+1)))
    while true; do
    	let cnt++
    	read -p "请输入一个您觉得可能出现的正整数(100以内): " num
    	if [[ $num =~ ^[0-9]+$ ]]; then
    		if [ $num -gt 100 ]; then
    			echo "超过100的值一律当作垃圾扔了..."
    		elif [ $num -gt $rand ]; then
    			echo "输入的值有点大啊! $num"
    		elif [ $num -lt $rand ]; then
    			echo "输入的值小了哎! $num"
    		elif [ $num -eq $rand ]; then
    			echo "恭喜您!猜对了!正是: $rand\n您总共猜了${cnt}次."
    			exit 0
    		fi
    	else
    		echo "您怕是输入了字符了,咱们要的是正整数. $num"
    	fi
    done	
    
  3. 破解经过md5sum简单加密的数字

    执行:

    #$var介于任意一个小于32768的正整数,如123
    echo "123" | md5sum | cut -c1-8
    #将输出值复制,稍后会用到该值
    

    上面的代码会生成一个经过MD5计算过后的字符串,然后取前8位字符输出;我们将使用该8位字符串进行逆向运算,通过MD5反推出原始的123

    版本1:通过$RANDOM变量随机生成,一且随缘

    #!/bin/bash
    #只能进行32767以内的正整数的MD5进行逆向破解,比较鸡肋
    read -p "请输入要破解的MD5: " key
    key_cnt=$(echo "$key"|wc -L)
    if [ $key_cnt -gt 8 -o $key_cnt -lt 8 ]; then
    	echo "必须输入8位有效的MD5值。 $key_cnt"
    	exit 1
    else
    	while true; do
            rand=$(echo "$RANDOM")
            md5=$(echo "$rand" | md5sum | cut -c1-8)
            echo "当前键值对   RAND:$rand    MD5:$md5"
            if [ $md5 = $key ]; then
                    echo "$key 对应的数字为 $rand"
                    exit 0
            fi
    	done
    fi
    

    版本2:使用let ++递增,短的快,长的慢

    #!/bin/bash
    #初始化标志和初始值
    flag=0
    read -p "请输入要破解的MD5: " key
    key_cnt=$(echo "$key"|wc -L)
    if [ $key_cnt -gt 8 -o $key_cnt -lt 8 ]; then
    	echo "必须输入8位有效的MD5值。 $key_cnt"
    	exit 1
    else
    	while [ $flag -eq 0 ]; do
    		let rand++
            md5=$(echo "$rand" | md5sum | cut -c1-8)
            echo "当前键值对   RAND:$rand    MD5:$md5"
            if [ $md5 = $key ]; then
                    echo -e "结果:\n\a$key 对应的数字为 $rand"
                    flag=1
            fi
    	done
    	exit 0
    fi
    
# shell  bash 

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×