流程控制
分支结构、循环结构
分支结构
if 条件判断、case 分支匹配
if 条件判断
-
单分支
if 条件判断式 then 动作 fi
-
双分支
if 条件判断式 then 动作1 else 动作2 fi
-
多分支
if 条件判断式1 then 动作1 else if 条件判断式2 # elif 可以这样写 then 动作2 elif 条件判断式n then 动作n else 动作 fi
例1:单分支
-
~/.bash_profile
# .bash_profile # Get the aliases and functions if [ -f ~/.bashrc ]; then #判断有,这个文件 . ~/.bashrc #则,调用这个文件 fi # User specific environment and startup programs
例2:双分支
-
/etc/bashrc
if [ -e /etc/sysconfig/bash-prompt-xterm ]; then # -e 仅判断文件是否存在,不判断类型 PROMPT_COMMAND=/etc/sysconfig/bash-prompt-xterm else PROMPT_COMMAND='printf "\033]0:%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/\~}"' fi
例3:多分支
-
判断文件类型
#!/bin/bash read -p "请输入需要判断的文件名" file if [ -L "$file" ] # -L 表示软链接 then echo "${file}是一个软链接文件" elif [ -f "$file" ] then echo "${file}是一个普通文件" elif [ -d "$file" ] then echo "${file}是一个目录文件" else echo "${file}是一个不常见类型文件,例如:块设备、字符设备、套接字、管道符" fi
注:软链接目录的结尾加 “/” 表示其源文件目录,不加,表示文件
例4:分支嵌套
-
判断文件类型 —— 判断软链接最好进行优先判断,软链接存在源文件的类型关系
#!/bin/bash read -p "请输入需要判断的文件名:" file if [ -L "$file" ] ; then # -L 表示软链接 if [ -f "$file" ] ; then # 进行二次判断其源文件的文件类型 echo "${file}是一个软链接文件,源文件是普通文件" elif [ -d "$file" ] ; then echo "${file}是一个软链接文件,源文件是目录文件" else echo "${file}是一个不常见类型文件,例如:块设备、字符设备、套接字、管道符" fi elif [ -f "$file" ] ; then echo "${file}是一个普通文件" elif [ -d "$file" ] ; then echo "${file}是一个目录文件" else echo "${file}是一个不常见类型文件,例如:块设备、字符设备、套接字、管道符" fi
注:Linux 不以文件后缀名区分文件类型,但是还是会以文件后缀名区分文件显示规则
例:编写一个定时检查磁盘使用情况的脚本,并写好其定时计划任务
-
使用 df -h 检查已挂载的分区使用情况
[root@localhost ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/centos-home 1.0T 650G 374G 64% /home
-
编写脚本 check_disk.sh,检查过滤,/home 的 Use%,达到 80% 提醒
#/bin/bash used=$(df -h|grep "home$"|awk '{print $5}'|cut -d% -f1) if [ $used -ge 80 ] then echo "$(date +%Y-%m-%d_%H:%M:%S) /home分区使用率超过80%了,请抓紧扩容。" >> /tmp/check.log fi
-
定时计划任务,crontab -e
0 4 * * * bash /root/check_disk.sh # 每天凌晨四点整,执行 bash /root/check_disk.sh
查看日志:tailf /var/log/cron —— 查看脚本调用的记录
case 分支匹配 —— 匹配多种可能性,可以预设匹配条件
-
格式:
case "变量" in 预设值1) #变量和预设值相匹配,就执行动作 动作1 ;; 预设值2) 动作2 ;; ... esac
补充:/etc/init.d/ —— 服务启动管理目录,也可以管理脚本(CentOS 6)
例:下载源码包 nginx —— nginx.org
-
将 nginx 的启动管理交给脚本执行 —— 叠加 PATH 环境变量,/bash
[root@localhost ~]# vim ~/.bash_profile #User specific environment if ! [[ "$PATH" =~ "$HOME/.local/bin:$HOME/bin:" ]] then PATH="$HOME/.local/bin:$HOME/bin:$PATH:/bash" #环境变量叠加一个 /bash目录 fi export PATH
-
编辑后,载入配置文件
source /root/.bash_profile # 加载配置文件,使之生效
-
编辑脚本,nginx —— 做源码包服务管理
[root@localhost ~]# vim nginx #!/bin/bash nginx="/usr/local/nginx/sbin/nginx" case "$1" in # 调用脚本外的第一个值 start) $nginx # 说明,执行脚本 nginx start 表示开启 nginx ;; # ;; 表示结束,跳出 stop) $nginx -s stop ;; restart) $0 stop # "$0" 表示调用脚本本身,表示执行 nginx stop $0 start ;; test) $nginx -t # nginx -t,这是配置文件检查工具,检查语法是否有错 ;; *) # 其它输入情况,统一,给予提示 echo "Usage:$0 start|stop|restart|test" esac
-
添加可执行权限,然后移动到 /bash
[root@localhost ~]# chmod +x nginx ; mv ./nginx /bash [root@localhost ~]# nginx start ; ngingx stop ; nginx restart ; nginx test
注:可以临时性的,叠加环境变量 —— export PATH=$PATH:/bash
补充:dnf —— 比 yum 更强大的源码包管理命令,新版本软件包管理机制 —— 支持自动搜索软件包
循环结构
for 循环 —— 计数循环
-
格式1
for i in 值的池 # $(命令) do 动作 done
-
格式2
for ((i=初始值;i<=最大值;i+=自增量)) do 动作 done
-
无限循环
for ((;;));do 动作 done
例:循环遍历输出
-
格式1
#!/bin/bash for i in nc1230 nc1231 nc1232 nc1233 do echo $i #依次,循环的输出 nc1230 nc1231 nc1232 nc1233 done ##################### 另一种写法 ##################### for i in $(find /etc/ -name "*.txt") # 使用命令取值 do echo $i done
-
格式2:做数值累加 1+2+3+4+…+100
#!/bin/bash sum=0 for ((i=1;i<=100;i++)) do sum=$(($sum+$i)) done ##################### 进一步完善 ##################### read -p "请输入最小值:" min read -p "请输入最大值:" max read -p "请输入累加值:" n sum=0 for ((i=$min;i<=$man;i+=$n)) do sum=$(($sum+$i)) done echo "${min} 到 ${max} 直接的累加结果是 ${sum}" # 输出
-
无限循环,输出随机数
#!/bin/bash for ((;;)) do echo $(($RANDOM%100)) # 0-99 的随机数 done ##################### 加上退出条件 ##################### for ((;;)) do num=$(($RANDOM%100));echo $num # 使用变量保存随机数 if [ "$num" -eq "88" ] # 若等于 88 then exit # 则,退出 fi done
注:RANDOM 是一个可以生成随机数字的环境变量
流程控制
流程控制语句
- exit —— 退出当前脚本
- break —— 退出当前循环,会继续执行循环结构以外的代码
- continue —— 仅跳过本次循环,继续执行后续的循环
当存在多循环嵌套时,可以使用数字执行跳出的层数
- break N
- continue N
例1:生成随机数,出现 88 则退出脚本
#!/bin/bash
for ((;;));do
num=$(($RANDOM%100));echo $num
if [ "$num" -eq "88" ];then # 出现 88
exit # 退出脚本
fi
done
echo "hello world"
说明:循环输出随机数字,出现 88 以后,脚本直接退出,hello world 不会被输出
例2:生成随机数,出现 88 则退出循环结构
#!/bin/bash
for ((;;));do
num=$(($RANDOM%100));echo $num
if [ "$num" -eq "88" ];then
break
fi
done
echo "hello world" # break 仅退出循环,后续代码正常执行
说明:循环输出随机数字,出现 88 结束循环输出,hello world 正常输出
例3:顺序输出 1-9,仅跳过输出数字 5
#!/bin/bash
for i in 1 2 3 4 5 6 7 8 9
do
if [ "$i" -eq "5" ] #continue 仅退出符合条件的那一轮循环
then
continue
else
echo $num
fi
done
echo "hello world"
说明:continue 仅跳过一轮循环,所以数字 5 不会被输出,跳过后,循环和后续代码正常执行
补充:双层循环嵌套 —— 输出 99乘法表
#!/bin/bash
for i in $(seq 9);do
for j in $(seq $i);do
echo -en "${i}x${j}=$(($i*$j))\t" # -en 配合 \t 规定输出格式
done
echo # 换行
done
说明 —— seq 命令
- seq 9 —— 输出 1-9
- seq 5 9 —— 输出 5-9
- seq 5 2 9 —— 输出 5-9,每次自增 2,也就是 5、7、9