shell脚本介绍
shell脚本结构和执行
实践操作:
[root@aminglinux ~]# mkdir shell [root@aminglinux ~]# cd shell/ [root@aminglinux shell]#
[root@aminglinux shell]# vi 1.sh #!/bin/bash echo "abc" w ls
[root@aminglinux shell]# sh 1.sh abc 15:17:34 up 5:30, 1 user, load average: 0.00, 0.01, 0.05 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root pts/0 192.168.222.1 09:48 6.00s 0.12s 0.05s w 1.sh
[root@aminglinux shell]# chmod a+x 1.sh
[root@aminglinux shell]# ./1.sh abc 15:21:19 up 5:33, 1 user, load average: 0.08, 0.03, 0.05 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root pts/0 192.168.222.1 09:48 7.00s 0.10s 0.00s w 1.sh
[root@aminglinux shell]# ll /bin/bash -rwxr-xr-x. 1 root root 960472 8月 3 2017 /bin/bash [root@aminglinux shell]# ll /bin/sh lrwxrwxrwx. 1 root root 4 6月 10 04:03 /bin/sh -> bash
[root@aminglinux shell]# /bin/bash 1.sh abc 15:26:49 up 5:39, 1 user, load average: 0.00, 0.01, 0.05 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root pts/0 192.168.222.1 09:48 1.00s 0.12s 0.01s w 1.sh
运行shell脚本有两种方法
[root@aminglinux shell]# /root/shell/1.sh abc 15:29:52 up 5:42, 1 user, load average: 0.16, 0.05, 0.06 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root pts/0 192.168.222.1 09:48 0.00s 0.13s 0.00s w 1.sh
[root@aminglinux shell]# sh -x 1.sh + echo abc abc + w 15:32:10 up 5:44, 1 user, load average: 0.02, 0.03, 0.05 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root pts/0 192.168.222.1 09:48 2.00s 0.14s 0.01s w + ls 1.sh
[root@aminglinux shell]# sh -n 1.sh
date命令用法
date命令用法实践
[root@aminglinux ~]# date 2018年 07月 29日 星期日 15:44:05 CST
date命令,在shell中用处非常大;对文件后缀增加一个时间,以便后期管理。
LANG=en //date命令显示的时间就是英文的 LANG=zh_CN.UTF-8 //date命令显示的时间是中文的
date +%Y-%m-%d, date +%y-%m-%d 年月日
[root@aminglinux ~]# LANG=en 切换为英文显示 [root@aminglinux ~]# date Wed Jul 11 23:01:05 CST 2018 [root@aminglinux ~]# date +%Y 2018 四位的年 [root@aminglinux ~]# date +%y 18 两位的年 [root@aminglinux ~]# date +%m 07 月份 [root@aminglinux ~]# date +%M 51 分钟 [root@aminglinux ~]# date +%d 29 日期 [root@aminglinux ~]# date +%D 07/29/18 直接标记年月日,不过格式比较特殊 [root@aminglinux ~]# date +%Y%m%d 20180729 年月日 [root@aminglinux ~]# date +%F 2018-07-29 年月日,这种带横杠的
[root@aminglinux ~]# date +%w 0 表示周几 [root@aminglinux ~]# date +%W 30 今年的第几周,今年的第28周 [root@aminglinux ~]# date +%h Jul 英文的月份 [root@aminglinux ~]# date +%H 15 小时 [root@aminglinux ~]# date +%S 26 秒 [root@aminglinux ~]# date +%s 1532850869 这是一个时间戳,距离1970总共过去多少秒
[root@aminglinux ~]# date +%T 15:56:18 [root@aminglinux ~]# date +%H:%M:%S 15:56:39
[root@aminglinux ~]# cal July 2018 Su Mo Tu We Th Fr Sa 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 31
学会用date标记之前的日期
[root@aminglinux ~]# date -d "-1 day" Sat Jul 28 16:01:23 CST 2018 [root@aminglinux ~]# date -d "-1 day" +%F 2018-07-28 [root@aminglinux ~]# date -d "-1 month" +%F 2018-06-29 [root@aminglinux ~]# date -d "-1 year" +%F 2017-07-29 [root@aminglinux ~]# date -d "+1 hour" +%T 17:02:53 [root@aminglinux ~]# date -d "+1 min" +%T 16:04:02
[root@aminglinux ~]# date +%s 1532851512 [root@aminglinux ~]# date -d @1532851512 Sun Jul 29 16:05:12 CST 2018
[root@aminglinux ~]# date +%s -d "2018-07-29 16:08:00" 1532851680 [root@aminglinux ~]# date -d @1532851680 Sun Jul 29 16:08:00 CST 2018
shell脚本中的变量
shell脚本中的变量:是某个字符串使用频繁,或者字符串长度长,可以使用变量才代替,提高代码编写的效率。
在条件语句中常使用到变量:
if [$a -gt 10];then 语句; fi //a就是变量
n='wc -l 1.txt' //wc统计行数命令的结果,赋值给变量n
read -p "input a number : " n; echo $n //把输入的数值,赋值给变量n
$0,$1,$2,$3等 //$0表示脚本本身,$1、$2代表命令的第1个参数、第2个参数,如此类推。$#代表参数个数
a=1 b=2 c=$(($a+$b)) //c=$[$a+$b] 这种写法也行
shell脚本中的逻辑判断
shell脚本中的逻辑判断实战
[root@aminglinux ~]# for i in `seq 1 5`;do echo $i;done 1 2 3 4 5 [root@aminglinux ~]# for i in `seq 1 5` > do > echo $i > done 1 2 3 4 5
[root@aminglinux shell]# vim if1.sh #!/bin/bash a=5 if [ $a -gt 3 ] then echo OK fi [root@aminglinux shell]# sh if1.sh OK
[root@aminglinux shell]# cp if1.sh if2.sh [root@aminglinux shell]# vim if2.sh a=1 if [ $a -gt 3 ] then echo OK else echo nook fi [root@aminglinux shell]# sh -x if2.sh + a=1 + '[' 1 -gt 3 ']' + echo nook nook
[root@aminglinux shell]# vim if3.sh [root@aminglinux shell]# cat if3.sh #! /bin/bash a=6 if [ $a -lt 5 ] then echo "a<5" elif [ $a -gt 5 ] && [ $a -lt 9 ] then echo "59" fi [root@aminglinux shell]# sh -x if3.sh + a=6 + '[' 6 -lt 5 ']' + '[' 6 -gt 5 ']' + '[' 6 -lt 9 ']' + echo '5
逻辑判断表达式
可以使用 && || 结合多个条件
- if文件目录属性判断
文件目录属性判断实战
[ -f file ]判断是否是普通文件,且存在
[root@aminglinux shell]# vim file1.sh
[root@aminglinux shell]# cat file1.sh
#! /bin/bash
f="/tmp/aminglinux1"
if [ -f $f ]
then
echo $f exist
else
touch $f
fi
[root@aminglinux shell]# sh -x file1.sh //第一次执行,会创建该文件
+ f=/tmp/aminglinux1
+ '[' -f /tmp/aminglinux1 ']'
+ touch /tmp/aminglinux1
[root@aminglinux shell]# sh -x file1.sh //第二次执行,会提示该文件已存在
+ f=/tmp/aminglinux1
+ '[' -f /tmp/aminglinux1 ']'
+ echo /tmp/aminglinux1 exist
/tmp/aminglinux1 exist
[ -d file ] 判断是否是目录,且存在
[root@aminglinux shell]# vim file2.sh [root@aminglinux shell]# cat file2.sh #! /bin/bash f="/tmp/aminglinuxd" if [ -d $f ] then echo $f exist else mkdir $f fi [root@aminglinux shell]# sh -x file2.sh + f=/tmp/aminglinuxd + '[' -d /tmp/aminglinuxd ']' + mkdir /tmp/aminglinuxd [root@aminglinux shell]# sh -x file2.sh + f=/tmp/aminglinuxd + '[' -d /tmp/aminglinuxd ']' + echo /tmp/aminglinuxd exist /tmp/aminglinuxd exist
[root@aminglinux shell]# vim file3.sh [root@aminglinux shell]# cat file3.sh #! /bin/bash f="/tmp/aminglinux1" if [ -e $f ] then echo $f exist else touch $f fi [root@aminglinux shell]# sh -x file3.sh + f=/tmp/aminglinux1 + '[' -e /tmp/aminglinux1 ']' + echo /tmp/aminglinux1 exist /tmp/aminglinux1 exist [root@aminglinux shell]# ll /tmp/ total 0 -rw-r--r-- 1 root root 0 Jul 29 17:23 aminglinux1
[root@aminglinux shell]# vim file4.sh [root@aminglinux shell]# cat file4.sh #! /bin/bash f="/tmp/aminglinux1" if [ -r $f ] then echo $f readable fi [root@aminglinux shell]# sh file4.sh /tmp/aminglinux1 readable
[root@aminglinux shell]# !vim vim file4.sh [root@aminglinux shell]# sh file4.sh /tmp/aminglinux1 writeadable [root@aminglinux shell]# !vim vim file4.sh [root@aminglinux shell]# sh file4.sh [root@aminglinux shell]# //因为文件 没有执行权限,所以没有输入出
f="/tmp/aminglinux1" [ -f $f ] && rm -f $f //前一条命令执行成功才会继续执行之后的命令 等同于下面的表达方式 if [ -f $f ] then rm -rf $f fi
f="/tmp/aminglinux1" [ -f $f ] || touch $f //前面命令不成功时,执行后面的命令 if [ ! -f $f ] // “!”表示了如果这条命令不成功,就往下执行 then touch $f fi
if 特殊用法
if [ -z "$a" ] 这个表示当变量a的值为空时会怎么样
if [ -n "$a" ] 表示当变量a的值不为空
if grep -q '123' 1.txt; then 表示如果1.txt中含有'123'的行时会怎么样
if [ ! -e file ]; then 表示文件不存在时会怎么样
if (($a<1)); then …等同于 if [ $a -lt 1 ]; then…
中不能使用<,>,==,!=,>=,<=这样的符号
-n 判断变量的时候,需要用""双引号引起来,若是文件的时候,则不需要用双引号引起来
[root@aminglinux shell]# ls 1.sh file1.sh file2.sh file3.sh file4.sh if1.sh if2.sh if3.sh [root@aminglinux shell]# if [ -n 1.sh ]; then echo ok; fi ok [root@aminglinux shell]# if [ -n "$b" ]; then echo $b; else echo "b is null"; fi //当变量为空时时输出 b is null
[root@aminglinux shell]# grep -w 'zabbix' /etc/passwd //查看zabbix用户是否存在 zabbix:x:996:993:Zabbix Monitoring System:/var/lib/zabbix:/sbin/nologin [root@aminglinux shell]# if grep -wq 'zabbix' /etc/passwd; then echo "zabbix exist"; fi //-q ,表示把grep -w的值过滤掉 zabbix exist
[root@aminglinux shell]# if ! grep -wq 'zabbix' /etc/passwd; then echo useradd zabbix; fi //当没有zabix用户时创建用户,因zabbix用户存在,所以没有输出; [root@aminglinux shell]#
case判断
shell脚本案例:
脚本目的是 输入一个数字,然后用脚本去判断这个数字的范围
[root@aminglinux shell]# vim case.sh #!/bin/bash #判断是否输入有数值,空直接结束整个文本 read -p "Please input a number: " n #read 让用户输出一些字符串;赋值给最后一个变量;这里的赋值是“n” if [ -z "$n" ] //变量n 为空 then echo "Please input a number." exit 1 // 知识点 1 fi #n1将输入的数值清空数字,检查变量是否为空,如果不为空,就证明输入有其他的字符,告知用户,请输入一个数字 n1=`echo $n|sed 's/[0-9]//g'` //确定,n变量是否为数字 if [ -n "$n1" ] then echo "Please input a number." exit 1 fi if [ $n -lt 60 ] && [ $n -ge 0 ] 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 fi case $tag in 1) echo "not ok" ;; 2) echo "ok" ;; 3) echo "ook" ;; 4) echo "oook" ;; *) echo "The input value exceeds the calculation range.The number range is 0-100." ;; esac
[root@aminglinux shell]# read -p " Please input a number: " n Please input a number: 100 //n赋值 100,输出为100 [root@aminglinux shell]# echo $n 100
shell 中 exit0 exit1 的区别:
for循环
案例1
[root@aminglinux shell]# vim for1.sh [root@aminglinux shell]# cat for1.sh #!/bin/bash sum=0 for i in `seq 1 100` #seq 1到100个数字 do sum=$[$sum+$i] echo $i done echo $sum [root@aminglinux shell]# sh -x for1.sh + sum=0 ++ seq 1 100 + for i in '`seq 1 100`' + sum=1 + echo 1 1 ...... + for i in '`seq 1 100`' + sum=5050 + echo 100 100 + echo 5050 5050
for循环案例2
[root@aminglinux shell]# vim for2.sh [root@aminglinux shell]# cat for2.sh #!/bin/bash cd /etc/ for a in `ls /etc/` do if [ -d $a ] then ls -d $a fi done
[root@aminglinux shell]# for a in `seq 1 3`; do echo $a; done 1 2 3 [root@aminglinux shell]# for a in 1 2 3; do echo $a; done 1 2 3
while循环
案例1
[root@aminglinux shell]# vim while1.sh [root@aminglinux shell]# cat while1.sh #!/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/local/sbin/mail.py [email protected] "load high" "$load" fi sleep 30 #休眠30秒,因为检查系统负载,不需要一直去检查,过一会再看 done [root@yong-01 shell]# sh -x while1.sh + : ++ w ++ head -1 ++ awk -F 'load average:' '{print $2}' ++ cut -d. -f1 + load=' 0' + '[' 0 -gt 10 ']' + sleep 30 若想这种脚本不意外的终止,可以打开screen,在screen跑脚本
知识点
while循环案例2
[root@aminglinux shell]# vim while2.sh [root@aminglinux shell]# cat while2.sh #!/bin/bash while : do read -p "Please input a number: " n if [ -z "$n" ] then echo "you need input sth." continue #continue 重新回到循环 fi n1=`echo $n|sed 's/[0-9]//g'` if [ -n "$n1" ] then echo "you just only input numbers." continue fi break #break 退出循环 done echo $n
break跳出循环
[root@aminglinux shell]# vim break.sh [root@aminglinux shell]# cat break.sh #!/bin/bash for i in `seq 1 5` do echo $i if [ $i -eq 3 ] #比较数字,用-eq ;若是比较的是字符串,那需要用 == then break fi echo $i done echo AAA
[root@aminglinux 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 AAA AAA
continue结束本次循环
[root@aminglinux shell]# vim continue.sh [root@aminglinux shell]# cat continue.sh #!/bin/bash for i in `seq 1 5` do echo $i if [ $i -eq 3 ] then continue fi echo $i done echo AAA
[root@aminglinux shell]# sh continue.sh 1 1 2 2 3 4 4 5 5 AAA
exit退出整个脚本
[root@aminglinux shell]# vim exit.sh [root@aminglinux shell]# cat exit.sh #!/bin/bash for i in `seq 1 5` do echo $i if [ $i -eq 3 ] then exit fi echo $i done echo AAA [root@aminglinux shell]# sh exit.sh 1 1 2 2 3