20.1 shell脚本介绍
20.2 shell脚本结构和执行
20.3 date命令用法
20.4 shell脚本中的变量
20.5 shell脚本中的逻辑判断
20.6 文件目录属性判断
20.7 if特殊用法
20.8/20.9 case判断
20.10 for循环
20.11/20.12 while循环
20.13 break跳出循环
20.14 continue结束本次循环
20.15 exit退出整个脚本
扩展
select用法 http://www.apelearn.com/bbs/thread-7950-1-1.htmlhtml
shell是一种脚本语言 和传统的开发语言比较,会比较简单shell
shell有本身的语法规则;可使用逻辑判断、循环等语法编程
能够自定义函数,目的就是为了减小重复的代码bash
shell是系统命令的集合less
shell脚本能够实现自动化运维,能大大增长咱们的运维效率运维
shell脚本的格式:函数
开头须要加#!/bin/bash 以#开头的行做为解释说明 脚本的名字以.sh结尾,用于区分这是一个shell脚本
示例中执行脚本会先输出123,在w查看系统负载,接着lsspa
执行脚本的方法:3d
一、sh 01.shhtm
二、给脚本文件增长可执行权限,也能够执行
chmod a+x 01.sh ./01.sh //当前目录下01.sh,相对路径 或者用绝对路径: /root/shell/01.sh
三、/bin/sh实际是bash的软链接;实际上是真正执行的是bash
/bin/sh 01.sh bash 01.sh
-x 查看脚本执行过程 bash -x 01.sh
-n查看脚本是否语法错误 bash -n 01.sh ,没有输出表明没有错误
去掉01.sh中的echo "123"的一个双引号,执行报错
经常使用格式
date +%Y-%m-%d, date +%y-%m-%d 年月日
date +%H:%M:%S = date +%T 时间
date +%s 时间戳
date -d @1504620492
date -d "+1day" 一天后
date -d "-1 day" 一天前
date -d "-1 month" 一月前
date -d "-1 min" 一分钟前
date +%w, date +%W 星期
date //当前的日期 cal //日历 date +%Y //大写Y 年份2018 date +%y //小写y 年份18 date +%m //小写m 月份07 date +%Y%m%d //年月日20180729 date +%F //大写F 日期格式2018-07-30 date +%H //大写H 小时09 date +%M //大写M 分钟17 date +%S //大写S 秒14 date +%s //小写s 时间戳1532913453 date +%T //大写T 常规时间09:17:53 date "+%Y-%m-%d %H:%M:%S %w" //所有时间列出 年月日 时分秒 星期
date -d "-1 day" //前一天的日期时间2018年 07月 28日 星期六 09:19:12 CST date -d "-1 day" +%F //带格式的 前一天的日期时间2018-07-29 date -d "-1 month" +%F // 带格式的 上一个月2018-06-29 date -d "-1 year" +%F //带格式的 上一个月2017-07-29 date -d "-1 hour" +%T //上一小时的时间08:19:54 date +%s -d "2019-06-14 21:24:08" //查看其对应的时间戳1560518648 date -d @1560518648 把时间戳换算成日期
当脚本中使用某个字符串较频繁而且字符串长度很长时就应该使用变量代替 使用条件语句时,常使用变量 if [ $a -gt 1 ]; then ... ; fi 引用某个命令的结果时,用变量替代 n=`wc -l 1.txt` 写和用户交互的脚本时,变量也是必不可少的 read -p "Input a number: " n; echo $n 若是没写这个n,能够直接使用$REPLY 内置变量 $0, $1, $2… $0表示脚本自己,$1 第一个参数,$2 第二个 .... $#表示参数个数 数学运算a=1;b=2; c=$(($a+$b))或者$[$a+$b]
格式1:if 条件 ; then 语句; fi 格式2:if 条件; then 语句; else 语句; fi 格式3:if …; then … ;elif …; then …; else …; fi 逻辑判断表达式:if [ $a -gt $b ]; if [ $a -lt 5 ]; if [ $b -eq 10 ]等 -gt (>); -lt(<); -ge(>=); -le(<=);-eq(==); -ne(!=) 注意处处都是空格
可使用 && || 结合多个条件
if [ $a -gt 5 ] && [ $a -lt 10 ]; then &&而且 if [ $b -gt 5 ] || [ $b -lt 3 ]; then ||或者
符号 |
释义 |
对应单词 |
-gt |
大于 |
greater than |
-lt |
小于 |
ess than |
-ge |
大于或等于 |
greater than or equal |
-le |
小于或等于 |
less than or equal |
-eq |
等于 |
equality |
-ne |
不等于 |
inequality |
格式1:if 条件 ; then 语句; fi
if [ $a -gt 3 ]; then echo ok; fi 若是a>3,那么输出ok
放到脚本中:
格式2:if 条件; then 语句; else 语句; fi
若是$a大于3,输出ok,不然输出no
格式3:if …; then … ;elif …; then …; else …; fi
#!/bin/bash read -p "请输入考试分数:" a if [ $a -lt 60 ] then echo "太差劲了!重考,未经过考试!" elif [ $a -ge 60 ] && [ $a -le 85 ] then echo "还行吧!经过考试,成绩良好!" else echo "恭喜你!经过考试,成绩优秀! " fi
[ -f file ]判断是不是普通文件,且存在
[ -d file ] 判断是不是目录,且存在
[ -e file ] 判断文件或目录是否存在
[ -r file ] 判断文件是否可读
[ -w file ] 判断文件是否可写
[ -x file ] 判断文件是否可执行
判断是不是普通文件,且存在: [ -f file ]
示例中判断/tmp/下的tobe文件是否存在,若是存在,输出/tmp/tobe exist,不存在则建立该目录
判断是不是目录,且存在: [ -d file ]
若是/tmp下的tobe123不是目录,mkdir建立,不然输出/tmp/tobe123 exist
而且 &&
f="/root/ceshi" [ -f $f ] && rm -f $f //前一条命令执行成功才会继续执行以后的命令 等同于下面的表达方式 if [ -f $f ] then rm -rf $f fi
或者 ||
f="/tmp/ttt123.txt" [ -f $f ] || touch $f //前面命令不成功时,即文件不存在,才会执行后面的命令,进行建立 等同于下面的表达方式 if [ ! -f $f ] // “!”表示了若是这条命令不成功,就往下执行 then touch $f fi
圆括号与方括号的区别:
if (($a<1)); then … 等同于 if [ $a -lt 1 ]; then…
[ ] 中不能使用<,>,==,!=,>=,<=这样的符号
#! /bin/bash n=`wc -l /etc/passwd |awk '{print $1}'` //输出/etc/passwd的行数 if [ -z "$n" ] //条件:是否为空 then echo error exit elif [ $n -gt 20 ] //条件:n是否大于20 then echo OK fi
if [ -n "$a" ] 表示当变量a的值不为空,或者说这个文件内容不为空
-n 判断变量的时候,须要用""双引号引发来,如果文件的时候,则不须要用双引号引发来
if [ -n "$b" ]; then echo $b; else echo "b is null"; fi 若是$b不为空,输出$b,不然输出b is null
-w精准匹配
-q 过滤,可是不显示过滤内容
if grep -wq 'user1' /etc/passwd;then echo "user1 is exist";fi 若是匹配到user1时,输出user1 is exist if ! grep -wq 'user1' /etc/passwd;then useradd user1;fi 若是匹配不到user1,则添加用户user1
格式:
case 变量名 in value1) command ;; value2) command ;; *) commond ;; esac
案例
read -p "Please input a number: " n //read让用户输入字符串,好比输入了1,那么n就会赋值1,即n=1
exit 1
#!/bin/bash read -p "Please input a number: " n //read让用户输入字符串,好比输入了1,那么n就会赋值1,即n=1 if [ -z "$n" ] //判断用户有没有输入 then echo "Please input a number." exit 1 fi n1=`echo $n|sed 's/[0-9]//g'` //检查用户输入的是否是所有是数字,不是数字就置空 if [ -n "$n1" ] then echo "Please input aa number." exit 1 fi if [ $n -lt 60 ] && [ $n -ge 0 ] //通过如上的筛选,咱们来判断输入数字属于哪一个范围,而且把值交给tag then tag=1 elif [ $n -ge 60 ] && [ $n -lt 80 ] then tag=2 elif [ $n -ge 80 ] && [ $n -lt 90 ] then tag=3 elif [ $n -ge 90 ] && [ $n -le 100 ] then tag=4 else tag=0 //大于100的状况 fi case $tag in //根据如上获得的值,进行判断 1) 表示第一个条件 echo "not ok" 值为1时,输出此内容 ;; 2) echo "ok" 值为2时,输出此内容 ;; 3) echo "ok ok" ;; 4) echo "perfect" ;; *) * 表明除此以外的 echo "Pls input a number range 0-100" ;; esac
重复执行一系列命令在 编程中很常见。一般你须要重复一组命令直到达到某个特定条件,好比处理某个目录下的全部文件、系统上的全部用户或者是某个文本文件中的全部行。
常见的两种循环,在脚本中广泛被用到。
for循环
while循环
语法:for 变量名 in 条件; do …; done
示例一:累加求和
能够看到运算过程
#!/bin/bash sum=0 for i in `seq 1 10` do echo "$sum + $i" sum=$[$sum+$i] echo $sum done echo $sum
直接计算
#!/bin/bash sum=0 for i in `seq 1 10` do sum=$[$sum+$i] done echo $sum
案例2
遍历一个目录或者文件
#!/bin/bashcd cd /etc/ //进入到目录 for a in `ls /etc/` //遍历此目录 do [ -d $a ] && ls $a # 判断是不是目录,并列出其下文件和子目录 if [ -d $a ] then echo $a ls $a fi done
for循环会以空格或回车为分隔符
语法 while 条件; do … ; done
案例1:
每隔1分钟检查一下系统负载,当系统的负载大于10的时候,发一封邮件(监控脚本) 最小单元是任务计划 cron
#!/bin/bash while : # 冒号 : 表示死循环的意思,或者1,或者 true都是死循环 do load=`w|head -1|awk -F 'load average: ' '{print $2}'|cut -d. -f1` if [ $load -gt 10 ] then /usr/lib/zabbix/alertscripts/mail.py foutt7777@163.com "load high" "$load" fi sleep 30 #休眠30秒,由于检查系统负载,不须要一直去检查,过一会再看 done
代码名词释义
w :查看系统负载 ;
uptime 能够直接显示 w 系统负载的第一行,就能够省去 head -1
head -1 //取第一行
awk -F 'load average: ' '{print $2}' // 以'load average: '分隔,输出第二段
cut -d . -f1 // 以 . 分隔 取第一段
休眠30秒后会一直检查
while循环案例2
在循环过程过,须要用户输入一个数字;输入的不是数字或输入为空;回应相应的结果
#!/bin/bash while : do read -p "Please input a number: " n if [ -z "$n" ] 若是内容是空的,那么$n为空;若是有内容,执行下面的n1=`echo $n|sed 's/[0-9]//g'` then echo "须要输入." 那么echo continue continue 从新回到循环,继续执行上面的操做 fi n1=`echo $n|sed 's/[0-9]//g'` 判断是不是纯数字 if [ -n "$n1" ] ! -z = -n then echo "你只能输入一个纯数字." continue fi break break 退出循环 done echo $n
break 经常使用于循环语句中,跳出整个循环语句,直接结束全部循环。
#!/bin/bash for i in `seq 1 5` do echo A=$i if [ $i -eq 3 ] #比较数字,用-eq ;如果比较的是字符串,那须要用 == then break 等于3时,调出循环 fi echo B=$i done echo C=$i
#!/bin/bash for i in `seq 1 5` do echo A=$i if [ $i -eq 3 ] then continue fi echo B=$i done echo abc
注意没有B=3行
exit能够定义退出的数值,能够用于肯定脚本运行到什么地方的时候结束
#!/bin/bash for i in `seq 1 5` do echo A=$i if [ $i -eq 3 ] then exit fi echo B=$i done echo C=$i
直接从A=3退出