20.1 shell 脚本介绍html
shell是一种脚本语言linux
可使用逻辑判断、循环等语法shell
能够自定义函数vim
shell是系统命令的集合bash
shell脚本能够实现自动化运维,能大大增长咱们的运维效率运维
20.2 shell 脚本结构和执行ide
开头须要加 #!/bin/bash,不加开头在本机上能够运行,换台机器就不必定能执行。在行首文件头处指定接下来要运行的命令是经过哪个解释器进行操做的。函数
以#开头的行做为解释说明,脚本的名字以 .sh 结尾,用于区分这是一个 shell 脚本优化
执行方法有两种:spa
一、/bin/bash 实际上就是 /bin/sh
[root@arslinux-01 ~]# ll /bin/sh lrwxrwxrwx. 1 root root 4 3月 14 05:51 /bin/sh -> bash [root@arslinux-01 ~]# ll /bin/bash -rwxr-xr-x. 1 root root 964608 10月 31 2018 /bin/bash
二、给文件执行权限,chmod a+x 1.sh 才能够 ./1.sh
[root@arslinux-01 shell]# ./1.sh -bash: ./1.sh: 权限不够 [root@arslinux-01 shell]# chmod a+x 1.sh [root@arslinux-01 shell]# ./1.sh 123 22:43:46 up 2:39, 1 user, load average: 0.10, 0.09, 0.13 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root pts/0 192.168.194.1 20:08 2.00s 2:44 0.00s /bin/bash ./1.sh 1.sh
三、若是没有权限,能够 /bin/bash 1.sh
[root@arslinux-01 shell]# /bin/bash 1.sh [root@arslinux-01shell]# /bin/bash 1.sh 123 22:48:59 up 2:44, 1 user, load average: 0.01, 0.05, 0.11 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root pts/0 192.168.194.1 20:08 3.00s 2:51 0.00s /bin/bash 1.sh 1.sh
查看脚本执行过程: bash -x 1.sh
查看脚本是否语法错误: bash -n 1.sh
20.3 date 命令用法
[root@arslinux-01 ~]# date 2019年 06月 15日 星期六 23:11:02 CST
date +%Y-%m-%d, date +%y-%m-%d 年月日
[root@arslinux-01 ~]# date +%Y-%m-%d 2019-06-15 [root@arslinux-01 ~]# date +%y-%m-%d 19-06-15 [root@arslinux-01 ~]# date +%Y //年 2019 [root@arslinux-01 ~]# date +%M //分钟 14 [root@arslinux-01 ~]# date +%D 06/15/19 [root@arslinux-01 ~]# date +%F 2019-06-15 [root@arslinux-01 ~]# date +%S //秒 09 [root@arslinux-01 ~]# date +%s //时间戳,距离 1970.01.01.00:00:00 多少秒 1560611775
date +%H:%M:%S = date +%T 时间
[root@arslinux-01 ~]# date +%H:%M:%S 23:18:23 [root@arslinux-01 ~]# date +%T 23:18:29 [root@arslinux-01 ~]# date +%h 6月 [root@arslinux-01 ~]# date +%m 06
date +%s 时间戳
[root@arslinux-01 ~]# date +%s 1560612094 距离 1970.01.01.00:00:00 多少秒
date +%w, date +%W 星期
[root@arslinux-01 ~]# date +%w //星期几 6 [root@arslinux-01 ~]# date +%W //几年的第几周 23
cal 日历形式查看日期
[root@arslinux-01 ~]# cal 六月 2019 日 一 二 三 四 五 六 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
date -d "-1 day" 一天前
[root@arslinux-01 ~]# date -d "-1 day" 2019年 06月 14日 星期五 23:26:15 CST [root@arslinux-01 ~]# date -d "-1 day" +%F 2019-06-14
date -d "+1day" 一天后
[root@arslinux-01 ~]# date -d "+1 day" +%F 2019-06-16
date -d "-1 month" 一月前
[root@arslinux-01 ~]# date -d "-1 month" +%F 2019-05-15 [root@arslinux-01 ~]# date -d "-1 year" +%F 2018-06-15 [root@arslinux-01 ~]# date -d "-1 week" +%F 2019-06-08
date -d "-1 min" 一分钟前
[root@arslinux-01 ~]# date -d "-1 min" +%T 23:28:02
date -d @1504620492 根据时间戳换算成日期
[root@arslinux-01 ~]# date -d @1504620492 2017年 09月 05日 星期二 22:08:12 CST
date +%s -d "2019-09-09 09:09:09" 把具体的日期换算成时间戳
[root@arslinux-01 ~]# date +%s -d "2019-09-09 09:09:09" 1567991349
20.4 shell 脚本中的变量
当脚本中使用某个字符串较频繁而且字符串长度很长时就应该使用变量代替
使用条件语句时,常使用变量 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]
20.5 shell 脚本中的逻辑判断
格式1:if 条件;then 语句;fi
[root@arslinux-01 ~]# vim 01.sh #/bin/bash a=5 if [ $a -gt 3 ] then echo ok fi
格式2:if 条件;then 语句;else 语句;fi
[root@arslinux-01 shell]# vim 02.sh
#/bin/bash a=1 if [ $a -gt 3 ] then echo ok else echo not ok fi
[root@arslinux-01 shell]# sh -x 02.sh + a=1 + '[' 1 -gt 3 ']' + echo not ok not ok
格式3:if ...;then ...;elif ...;then ...;else ...;fi
[root@arslinux-01 shell]# vim 03.sh #/bin/bash a=3 if [ $a -gt 4 ] then echo ">4" elif [ $a -lt 6 ] then echo "<6 && >1" else echo not ok fi
[root@arslinux-01 shell]# sh -x 03.sh + a=3 + '[' 3 -gt 4 ']' + '[' 3 -lt 6 ']' + echo '<6 && >1' <6 && >1
[root@arslinux-01 shell]# vim 03.sh #/bin/bash a=5 if [ $a -lt 4 ] then echo "<4" elif [ $a -gt 6 ] then echo ">6" else echo not ok fi
[root@arslinux-01 shell]# sh -x 03.sh + a=5 + '[' 5 -lt 4 ']' + '[' 5 -gt 6 ']' + echo not ok not ok
逻辑判断表达式:
if [ $a -gt $b ]; -gt (>); 大于
if [ $a -lt 5 ]; -lt(<); 小于
if [ $b -eq 10 ]等 -eq(==); 等于
-le(<=);-ge(>=); -ne(!=) 注意处处都是空格
·若是非要用 > < ,能够用(( ))
[root@localhost shell]# if (($a>1));then echo ok;fi ok
·可使用 && || 结合多个条件
if [ $a -gt 5 ] && [ $a -lt 10 ]; then 而且
if [ $b -gt 5 ] || [ $b -lt 3 ]; then 或者
20.6 文件目录属性判断
·[ -f file ] 判断是不是普通文件,且存在
·[ -d file ] 判断是不是目录,且存在
·[ -e file ] 判断文件或目录是否存在
·[ -r file ] 判断文件是否可读
·[ -w file ] 判断文件是否可写
·[ -x file ] 判断文件是否可执行
[ -f file ] 判断是不是普通文件,且存在
[root@arslinux-01 shell]# vim 04.sh #/bin/bash f="/tmp/arslinux" if [ -f $f ] then echo $f exist. else touch $f fi
[root@arslinux-01 shell]# sh -x 04.sh + f=/tmp/arslinux + '[' -f /tmp/arslinux ']' + touch /tmp/arslinux [root@arslinux-01 shell]# sh -x 04.sh + f=/tmp/arslinux + '[' -f /tmp/arslinux ']' + echo /tmp/arslinux exist. /tmp/arslinux exist.
[ -d file ] 判断是不是目录,且存在
[root@arslinux-01 shell]# vim file2.sh #/bin/bash f="/tmp/arslinux" if [ -d $f ] then echo $f exist. else touch $f fi
[root@arslinux-01 shell]# sh -x file2.sh + f=/tmp/arslinux + '[' -d /tmp/arslinux ']' + touch /tmp/arslinux
[ -e file ] 判断文件或目录是否存在
[root@arslinux-01 shell]# vim file3.sh #/bin/bash f="/tmp/arslinux" if [ -e $f ] then echo $f exist. else touch $f fi
[root@arslinux-01 shell]# sh -x file3.sh + f=/tmp/arslinux + '[' -e /tmp/arslinux ']' + echo /tmp/arslinux exist. /tmp/arslinux exist.
[ -r file ] 判断文件是否可读
[root@arslinux-01 shell]# vim file4.sh #/bin/bash f="/tmp/arslinux" if [ -r $f ] then echo $f readable. fi
[root@arslinux-01 shell]# sh -x file4.sh + f=/tmp/arslinux + '[' -r /tmp/arslinux ']' + echo /tmp/arslinux readable. /tmp/arslinux readable.
[ -w file ] 判断文件是否可写
[root@arslinux-01 shell]# vim file4.sh #/bin/bash f="/tmp/arslinux" if [ -w $f ] then echo $f writeable. fi
[root@arslinux-01 shell]# sh -x file4.sh + f=/tmp/arslinux + '[' -w /tmp/arslinux ']' + echo /tmp/arslinux writeable. /tmp/arslinux writeable.
[ -x file ] 判断文件是否可执行
[root@arslinux-01 shell]# vim file4.sh
#/bin/bash f="/tmp/arslinux" if [ -x $f ] then echo $f exeable. fi
[root@arslinux-01 shell]# sh -x file4.sh + f=/tmp/arslinux + '[' -x /tmp/arslinux ']'
简单写法
#!/bin/bash f="/tmp/alex" if [ -f $f ] then rm -f $f fi
能够不用 if 判断写成
#!/bin/bash f="/tmp/alex" [ -f $f ] && rm -f $f
#!/bin/bash f="/tmp/alex" if [ -f $f ] then rm -f $f else touch $f fi
能够反写为
#!/bin/bash f="/tmp/alex" if [ ! -f $f ] then touch $f fi
能够不用 if 判断,写成
#!/bin/bash f="/tmp/alex" [ -f $f ] || touch $f
20.7 if 特殊用法
if [ -z "$a" ] 这个表示当变量 a 的值为空时会怎么样
#!/bin/bash n=`wc -l /tmp/bababa` if [ -z "$n" ] then echo error else if [ $n -gt 100] then echo ok fi fi
能够优化为:
#!/bin/bash n=`wc -l /tmp/bababa` if [ -z "$n" ] then echo error exit elif [ $n -gt 100] then echo ok fi
能够再优化:
#!/bin/bash if [ -f /tmp/babala ] then echo "/tmp/babala isn't exist." exit fi n=`wc -l /tmp/bababa` if [ -z "$n" ] then echo error exit elif [ $n -gt 100] then echo ok fi
if [ -n "$a" ] 表示当变量 a 的值不为空
[root@arslinux-01 shell]# if [ -n 01.sh ];then echo ok;fi ok [root@arslinux-01 shell]# if [ -n "$b" ];then echo "$b";else echo "b is null";fi b is null
命令能够做为判断结果
if grep -q '123' 1.txt; then 表示若是1.txt中含有'123'的行时会怎么样
[root@arslinux-01 shell]# if grep -w 'user1' /etc/passwd;then echo "user1 exist";fi user1:x:1001:1001::/home/user1:/bin/bash user1 exist [root@arslinux-01 shell]# if grep -wq 'user1' /etc/passwd;then echo "user1 exist";fi user1 exist
grep -q 静默输出
if [ ! -e file ]; then 表示文件不存在时会怎么样
if (($a<1)); then …等同于 if [ $a -lt 1 ]; then…
[ ] 中不能使用<,>,==,!=,>=,<=这样的符号
20.8/20.9 case 判断
格式:case 变量名 in
value1)
command
;;
value2)
command
;;
*)
commond
;;
esac
:: 表示一个判断结束,进入下一个判断
在case程序中,能够在条件中使用|,表示或的意思, 好比
2|3)
command
;;
*)除以上全部以外的
shell 脚本案例
#!/bin/bash read -p "Please input a number: " n //从标准输入读取输入并赋值给变量 n if [ -z "$n" ] then echo "Please input a number." exit 1 fi n1=`echo $n|sed 's/[0-9]//g'` //从变量n中将数字替换为空,若是n1不为空,则不是纯数字,那么现实输入一个数字并退出 if [ -n "$n1" ] then echo "Please input a number." exit 1 fi if [ $n -lt 60 ] && [ $n -ge 0 ]//纯数字往下接着判断 then tag=1 //标记tag 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 fi case $tag in 1) echo "not ok" ;; 2) echo "ok" ;; 3) echo "great" ;; 4) echo "brilliant" ;; *) echo "The number range is 0-100." ;; esac
执行脚本看结果:
输入符合条件的纯数字
[root@arslinux-01 shell]# sh -x case.sh + read -p 'Please input a number: ' n Please input a number: 77 + '[' -z 77 ']' ++ echo 77 ++ sed 's/[0-9]//g' + n1= + '[' -n '' ']' + '[' 77 -lt 60 ']' + '[' 77 -ge 60 ']' + '[' 77 -lt 80 ']' + tag=2 + case $tag in + echo ok ok
输入含字母的数字组合
[root@arslinux-01 shell]# sh -x case.sh + read -p 'Please input a number: ' n Please input a number: l33l + '[' -z l33l ']' ++ echo l33l ++ sed 's/[0-9]//g' + n1=ll + '[' -n ll ']' + echo 'Please input a number.' Please input a number. + exit 1
输入大于 100 的数字
[root@arslinux-01 shell]# sh -x case.sh + read -p 'Please input a number: ' n Please input a number: 234 + '[' -z 234 ']' ++ echo 234 ++ sed 's/[0-9]//g' + n1= + '[' -n '' ']' + '[' 234 -lt 60 ']' + '[' 234 -ge 60 ']' + '[' 234 -lt 80 ']' + '[' 234 -ge 80 ']' + '[' 234 -lt 90 ']' + '[' 234 -ge 90 ']' + '[' 234 -le 100 ']' + tag=0 + case $tag in + echo 'The number range is 0-100.' The number range is 0-100.
20.10 for 循环
语法:for 变量名 in 条件; do …; done
案例1
计算1到100数字的和
[root@arslinux-01 shell]# vim for1.sh #!/bin/bash sum=0 for i in `seq 1 100` do sum=$[$sum+$i] done echo $sum
案例2
列出/etc/下的目录或子目录
[root@arslinux-01 shell]# sh for2.sh #!/bin/bash/ cd /etc/ for a in `ls /etc/` do if [ -d $a ] then ls -d $a fi done
ls 是用空格或回车做为分隔符,for 循环以他为对象,那么可能会出错
20.11/20.12 while循环
语法:while 条件; do … ; done
案例1
每隔半分钟检查系统负载,当负载大于10时,发邮件
[root@arslinux-01 shell]# vim while.sh #!/bin/bash while : do load=`w|head -1|awk -F 'load average: ' '{print $2}'|cut -d. -f1` if [ $load -gt 10] then /usr/local/sbin/mail.py xxx@163.com "load high" "$load" fi sleep 30 done
: 表示死循环 或者写成 while true
案例2
作一个让人让用户不停输入东西的脚本
[root@arslinux-01 shell]# vim while2.sh #!/bin/bash while : do read -p "Please input a number: " n if [ -z "$n" ] then echo "you need input sth." continue fi n1=`echo $n|sed 's/[0-9]//g'` if [ -n "$n1" ] then echo "you just only input numbers." continue fi break done echo $n
continue 指继续从新再来一遍循环
continue 从头继续从新再来一遍循环
break 退出 while 循环
20.13 break跳出循环
[root@arslinux-01 shell]# vim break.sh #!/bin/bash for i in `seq 1 5` do echo $i if [ $i -eq 3 ] then break fi echo $i done echo jjjjj
[root@arslinux-01 shell]# sh -x break.sh ++ seq 1 5 + for i in '`seq 1 5`' + echo 1 1 + '[' 1 -eq 3 ']' + echo 1 1 + for i in '`seq 1 5`' + echo 2 2 + '[' 2 -eq 3 ']' + echo 2 2 + for i in '`seq 1 5`' + echo 3 3 + '[' 3 -eq 3 ']' + break + echo jjjjj jjjjj
本来在 i 为 3 以前,脚本一直执行到done,而后在从头循环,而 为 3 时,之间break跳出循环,
echo aaaaaaa
break 用在循环语句里,for 也行,while 也行
20.14 continue结束本次循环
忽略continue之下的代码,直接进行下一次循环
[root@arslinux-01 shell]# vim continue.sh #!/bin/bash for i in `seq 1 5` do echo $i if [ $i -eq 3 ] then continue fi echo $i done echo jjjjj
[root@arslinux-01 shell]# sh -x continue.sh ++ seq 1 5 + for i in '`seq 1 5`' + echo 1 1 + '[' 1 -eq 3 ']' + echo 1 1 + for i in '`seq 1 5`' + echo 2 2 + '[' 2 -eq 3 ']' + echo 2 2 + for i in '`seq 1 5`' + echo 3 3 + '[' 3 -eq 3 ']' + continue + for i in '`seq 1 5`' + echo 4 4 + '[' 4 -eq 3 ']' + echo 4 4 + for i in '`seq 1 5`' + echo 5 5 + '[' 5 -eq 3 ']' + echo 5 5 + echo jjjjj jjjjj
break会跳出循环,再也不执行循环,而continue会结束本次循环,从头开始执行循环
20.15 exit退出整个脚本
[root@arslinux-01 shell]# vim exit.sh #!/bin/bash for i in `seq 1 5` do echo $i if [ $i -eq 3 ] then exit fi echo $i done echo jjjjj
[root@arslinux-01 shell]# sh -x exit.sh ++ seq 1 5 + for i in '`seq 1 5`' + echo 1 1 + '[' 1 -eq 3 ']' + echo 1 1 + for i in '`seq 1 5`' + echo 2 2 + '[' 2 -eq 3 ']' + echo 2 2 + for i in '`seq 1 5`' + echo 3 3 + '[' 3 -eq 3 ']' + exit
break 在跳出后还会执行最后的 echo,而 exit 直接退出
给 exit 定义退出的数字
[root@arslinux-01 shell]# vim exit.sh #!/bin/bash for i in `seq 1 5` do echo $i if [ $i -eq 3 ] then exit 2 fi echo $i done echo jjjjj
[root@arslinux-01 shell]# sh -x exit2.sh ++ seq 1 5 + for i in '`seq 1 5`' + echo 1 1 + '[' 1 -eq 3 ']' + echo 1 1 + for i in '`seq 1 5`' + echo 2 2 + '[' 2 -eq 3 ']' + echo 2 2 + for i in '`seq 1 5`' + echo 3 3 + '[' 3 -eq 3 ']' + exit 2 [root@arslinux-01 shell]# echo $? 2
continue 结束本次循环,继续循环,忽略后面的代码
break 结束整个循环,跳出
exit 直接退出整个脚本
扩展