第二十章 Shell编程(上)

20.1 Shell脚本介绍

20.2 Shell脚本结构和执行

20.3 date命令用法

Y年 m月 d日

[root@centos01 shell]# date +%Y%m%d
20181026

H小时 M分钟 S秒      

[root@centos01 shell]# date +%H-%M-%S
03-56-41

F 代表年月日

[root@centos01 shell]# date +%F
2018-10-26

T 代表小时 分钟 秒

[root@centos01 shell]# date +%T
03:25:34

s(小写)时间戳

把当前时间转换成时间戳

[root@centos01 shell]# date +%s
1540539856

把时间戳转换成时间
[root@centos01 shell]# date -d @1540539856
Fri Oct 26 03:44:16 EDT 2018

把以前的时间转换成时间戳
[root@centos01 shell]# date +%s -d "2017-10-26 03:44:16"
1509003856

把以前的时间戳转换成时间
[root@centos01 shell]# date -d @1509003856
Thu Oct 26 03:44:16 EDT 2017

w 周(0--6)0代表周日     

[root@centos01 shell]# date +%w
5


W(大写) 今年的第几周

[root@centos01 shell]# date +%W
43

-1 day  一天以前

date -d "-1 day" +%F

一小时以前

date -d "-1 hour"

一分钟以前

date -d "-1 min"

-1 month  一月以前

date -d "-1 month" +%F

-1 year  一年以前

date -d "-1 year" +%F

 

20.4 Shell脚本中的变量

20.5 Shell脚本中的逻辑判断

-gt 大于  -lt 小于  -ge 大于等于  -le 小于等于  -eq 等于  -ne 不等于

[ $a -gt 5 ] 注意方括号里面有空格

&& 并且  前面的成立的时候才会执行后面的

|| 或者  前面不成立的时候才会执行后面的

20.6 文件目录属性判断

 

20.7 if特殊用法

-w 精确匹配一个词   -q 匹配到不显示        !没有过滤到这个用户

20.8 case判断(上)

案例

#!/bin/bash
read -p "Please input a number: " n
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 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 "no good"
        ;;
    2)
        echo "good"
        ;;
    3)
        echo "very good"
        ;;
    4)
        echo "great"
        ;;
    *)
        echo "The number range is 0-100."
        ;; 
esac

20.10 for循环

ls 会以空隔为分隔符,注意!

20.11 while循环(上)

20.12 while循环(下)

20.13 break跳出循环

20.14 continue结束本次循环

执行过程

[root@centos01 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 ok
ok


20.15 exit退出整个脚本

课堂串讲

20.1 shell脚本介绍
20.2 shell脚本结构和执行
20.3 date命令用法
20.4 shell脚本中的变量

20.1 shell脚本介绍

shell是一种脚本语言。它既有自己的语法规制,可以使用逻辑判断、循环等语法,也可以自定义函数
shell是系统命令的集合,并且通过主机的语法可以对命令进行判断等。
shell脚本可以实现自动化运维,它能大大增加我们的运维效率。

20.2 Shell脚本结构和执行

  • shell脚本结构
    • 开头需要加#!/bin/bash #!/bin/bash是告诉系统通过/bin/bash解析器来解析操作脚本的
    • #开头的行作为解释说明
    • 脚本的名字以.sh结尾,用于区分这是一个shell脚本
1
[root@kun05 shell]# vim hello.sh
1
2
3
4
5
#!/bin/bash
# written by kun
# date 2018-7-11
echo "this is first shell script."
echo "Hello World!"
  • 执行方法有两种
    • chmod +x 1.sh; ./1.sh
    • bash 1.sh
1
2
3
4
[root@kun05 shell]# chmod a+x hello.sh
[root@kun05 shell]# ./hello.sh
this is first shell script.
Hello World!

也可以

1
2
3
[root@kun05 shell]# sh hello.sh
this is first shell script.
Hello World!

 

查看脚本执行过程 bash -x 1.sh

1
2
3
4
5
[root@kun05 shell]# sh -x hello.sh
+ echo 'this is first shell script.'
this is first shell script.
+ echo 'Hello World!'
Hello World!

查看脚本是否语法错误 bash -n 1.sh

1
2
3
4
5
6
#!/bin/bash
# written by kun
# date 2018-7-11
echo "this is first shell script."
echo "Hello World!"
for
1
2
3
[root@kun05 shell]# sh -n hello.sh
hello.sh:行6: 未预期的符号 `newline' 附近有语法错误
hello.sh:行6: `for '

这里是for循环没写完整

20.3 date命令用法

date 显示当前系统时间 在shell脚本中才用于标志时间

1
2
[root@kun05 shell]# date
2018年 07月 12日 星期四 05:45:33 CST
命令含义
date +%Y年(4位)
date +%y年(2位)
date +%m
date +%d
date +%D以 月/日/年 格式显示日期
date +%F以 年-月-日 格式显示日期
date +%H小时
date +%M分钟
date +%S
date +%T以时:分:秒 格式显示时间 等于 date +%H:%M:%S
date +%s时间戳 表示距离1970年1月1日到现的秒数
date +%w这个星期的第几周
date +%W今年的第几周
date +%h月份缩写 等于 date +%b
date -d “-1 day”一天前
date -d “+1 day”一天后
date -d “-1 year”一年前
date -d “-1 month”一个月前
date -d “-1 hour”一小时前
date -d “-1 min”一分钟前

显示日期

1
2
3
4
5
6
7
8
[root@kun05 shell]# date +%Y%m%d
20180712

[root@kun05 shell]# date +%D
07/12/18

[root@kun05 shell]# date +%F
2018-07-12

显示时间

1
2
[root@kun05 shell]# date +%T
06:02:30

显示时间戳

1
2
[root@kun05 shell]# date +%s
1531346417

显示一天后的时间

1
2
[root@kun05 shell]# date -d "+1 day" +%F
2018-07-13

显示一小时前的时间

1
2
[root@kun05 shell]# date -d "-1 hour" +%T
05:20:06

用时间戳来显示日期

1
2
[root@kun05 shell]# date -d @1531346417
2018年 07月 12日 星期四 06:00:17 CST

指定时间来显示对应的时间戳

1
2
[root@kun05 shell]# date +%s -d"2018-07-13 06:02:30"
1531432950

cal 显示系统日历

1
2
3
4
5
6
7
8
[root@kun05 shell]# cal
      七月 2018     
日 一 二 三 四 五 六
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

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脚本中的逻辑判断
20.6 文件目录属性判断
20.7 if特殊用法
20.8/20.9 case判断

20.5 Shell脚本中的逻辑判断

语法格式

格式1:if 条件 ; then 语句; fi

脚本形式

1
2
3
4
5
6
7
8
[root@kun05 shell]# vim if1.sh

#!/bin/bash
a=3
if [ $a -gt 2 ]
then
        echo ok
fi
1
2
[root@kun05 shell]# sh if1.sh
ok

命令行形式

1
2
3
[root@kun05 shell]# a=3
[root@kun05 shell]# if [ $a -gt 2 ];then echo ok;fi
ok

或者

1
2
3
4
5
[root@kun05 shell]# a=3
[root@kun05 shell]# if [ $a -gt 2 ]
> then echo ok
> fi
ok

 

格式2:if 条件; then 语句; else 语句; fi

1
2
3
4
5
6
7
8
9
10
[root@kun05 shell]# vim if2.sh

#!/bin/bash
a=1
if [ $a -gt 2 ]
then
        echo ok
else
        echo nook
fi
1
2
3
4
5
[root@kun05 shell]# sh -x if2.sh
+ a=1
+ '[' 1 -gt 2 ']'
+ echo nook
nook

格式3:if 条件1; then 语句1;elif 条件2; then 语句2; else 语句3; fi

意思为符合条件1则执行语句1,不符合则再判断是否符合条件2,都不符合则执行语句3

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@kun05 shell]# vim if3.sh

#!/bin/bash
a=2
if [ $a -eq 3 ]
then
        echo "the num = 3"
elif [ $a -gt 3 ]
then
        echo "the num > 3"
else
        echo "the num < 3"
fi

 

1
2
3
4
5
6
[root@kun05 shell]# sh -x if3.sh
+ a=2
+ '[' 2 -eq 3 ']'
+ '[' 2 -gt 3 ']'
+ echo 'the num < 3'
the num < 3

逻辑判断表达式:if [ $a -gt $b ] if [ $a -lt 5 ] if [ $b -eq 10 ]
也可以使用数学形式 if (($a>$b)) if(($a<5)) if(($b==10))
为了方便记忆 我们可以选择记忆带[]格式的表达式,但要注意[]两侧都是空格

参数数学符号含义
-gt>大于(greater than)
-lt<小于 (less than)
-eq==等于(equal)
-ge>=大于等于
-le<=小于等于
-ne!=不等于

可以使用 && ||结合多个条件
if [ $a -gt 5 ] && [ $a -lt 10 ] &&表示并且
if [ $b -gt 5 ] || [ $b -lt 3 ] ||表示或者

20.6 文件目录属性判断

参数含义
[ -f file ]判断是否是普通文件,且存在
[ -d file ]判断是否是目录,且存在
[ -e file ]判断文件或目录是否存在
[ -r file ]以当前用户来判断文件是否可读
[ -w file ]以当前用户来判断文件是否可写
[ -x file ]以当前用户来判断文件是否可执行

判断文件是否存在

1
2
3
4
5
6
7
8
9
10
[root@kun05 shell]# vim file1.sh

#!/bin/bash
f="/tmp/test"
if [ -f $f ]
then
        echo "$f exist"
else
        touch $f
fi

第一次文件不存在则创建文件

1
2
3
4
[root@kun05 shell]# sh -x file1.sh
+ f=/tmp/test
+ '[' -f /tmp/test ']'
+ touch /tmp/test

 

第二次文件存在

1
2
3
4
5
[root@kun05 shell]# sh -x file1.sh
+ f=/tmp/test
+ '[' -f /tmp/test ']'
+ echo '/tmp/test exist'
/tmp/test exist

 

判断文件/目录是否存在

1
2
3
4
5
6
#!/bin/bash
f="/tmp/test"
if [ -e $f ]
then
        touch $f
fi

即使已经存在了再touch则会更改文件/目录的是时间

判断文件是否可读

1
2
3
4
5
6
7
8
[root@kun05 shell]# vim file2.sh

#!/bin/bash
f="/tmp/test"
if [ -r $f ]
then
        echo "$f readable"
fi
1
2
[root@kun05 shell]# sh file2.sh
/tmp/test readable

有时候为了方便可以写成下面代码

1
2
3
#!/bin/bash
f="/tmp/test"
[ -f $f ] && rm -f $f

 

它表示文件存在则执行rm语句 等同于

1
2
3
4
5
6
#!/bin/bash
f="/tmp/test"
if [ -f $f ]
then
        rm -f $f
fi

 

[ -f $f ] || rm -f $f 它表示文件不存在则执行rm语句 等同于[ ! -f $f ] && rm -f $f

20.7 if特殊用法

参数含义
[ -z “$a” ]表示当变量a的值为空
[ -n “$a” ]表示当变量a的值不为空

判断变量是否不为空

1
2
3
4
5
6
7
8
[root@kun05 shell]# vim file3.sh

#!/bin/bash
f=/tmp/test
if [ -n "$f" ]
then
        echo ok
fi
1
2
[root@kun05 shell]# sh file3.sh
ok
  • 其他特殊用法

    • 使用命令来做判断条件

      1
      2
      
      [root@kun05 shell]# if grep -wq 'root' /etc/passwd;then echo root exist;fi
      root exist
      

      grep -w 'root'只搜索root此单词 -q 不在屏幕打印出来

    • 使用! 在参数前 表示取反 [ ! -e file ] 表示文件不存在
    • 中括号中不能使用<,>,==,!=,>=,<=这样的符号

20.8/20.9 case判断

语法格式

1
2
3
4
5
6
7
8
9
10
11
case  变量名 in 
                     value1)
                          command
                          ;;
                     value2)
                          command
                          ;;
                      *)
                        commond
                            ;;
                      esac

在case程序中,可以在条件中使用|,表示的意思, 比如

1
2
3
2|3) 
    command
    ;;

 

判断学生的成绩脚本

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
[root@kun05 shell]# vim case1.sh

#!/bin/bash
read -p "Please input number: " n
#让用户输入数字
if [ -z "$n" ]
then
        echo "Please input number: "
        exit 1
fi
#判断用户是否没填数字
n1=`echo $n|sed 's/[0-9]//g'`
if [ ! -z "$n1" ]
then
        echo "Please input number: "
        exit 1
fi
#判断用户是否填纯数字
if [ $n -lt 60 ]
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
#给分数赋值给tag
case $tag in
        1)
        echo "bu ji he"
        ;;
        2)
        echo "liang hao"
        ;;
        3)
        echo "you xiu"
        ;;
        4)
        echo "fei chang bang"
        ;;
        *)
        echo "The number range is 0-100"
        ;;
esac
#对tag进行判断
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
[root@kun05 shell]# sh -x case1.sh
+ read -p 'Please input number: ' n
Please input number: asdfsad
+ '[' -z asdfsad ']'
++ echo asdfsad
++ sed 's/[0-9]//g'
+ n1=asdfsad
+ '[' '!' -z asdfsad ']'
+ echo 'Please input number: '
Please input number:
+ exit 1

[root@kun05 shell]# sh -x case1.sh
+ read -p 'Please input number: ' n
Please input number: 89
+ '[' -z 89 ']'
++ echo 89
++ sed 's/[0-9]//g'
+ n1=
+ '[' '!' -z '' ']'
+ '[' 89 -lt 60 ']'
+ '[' 89 -ge 60 ']'
+ '[' 89 -lt 80 ']'
+ '[' 89 -ge 80 ']'
+ '[' 89 -lt 90 ']'
+ tag=3
+ case $tag in
+ echo 'you xiu'
you xiu

 

20.10 for循环
20.11/20.12 while循环
20.13 break跳出循环
20.14 continue结束本次循环
20.15 exit退出整个脚本

20.10 for循环

语法格式

1
for 变量名 in 条件; do …; done

计算出0到100的总和

1
2
3
4
5
6
7
8
9
[root@kun05 shell]# vim for1.sh

#!/bin/bash
sum=0
for i in `seq 1 100`
do
        sum=$[$i+$sum]
done
echo $sum
1
2
[root@kun05 shell]# sh for1.sh
5050

遍历/etc目录并把目录列出来

1
2
3
4
5
6
7
8
[root@kun05 shell]# vim for2.sh

#!/bin/bash
cd /etc
for i in `ls /etc`
do
        [ -d $i ] && ls $i
done

注意:for循环是以空格作为分隔符 ,因此文件名中到空格的要注意

1
2
3
4
5
6
7
8
[root@kun05 for]# touch 1 2
[root@kun05 for]# touch 3\ 4.txt

[root@kun05 for]# ll
总用量 0
-rw-r--r-- 1 root root 0 7月  14 05:07 1
-rw-r--r-- 1 root root 0 7月  14 05:07 2
-rw-r--r-- 1 root root 0 7月  14 05:07 3 4.txt

 

1
2
3
4
5
[root@kun05 for]# for i in `ls .`;do echo $i;done
1
2
3
4.txt

这里for循环把3 4.txt 分为了两个文件

20.11/20.12 while循环

语法格式

1
while 条件; do … ; done

每隔30秒查看系统负载,当大于10时发邮件

1
2
3
4
5
6
7
8
9
10
11
12
[root@kun05 shell]# vim while1.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 coco44566@163.com "load high" "$load"
        fi
        sleep 30
done
1
2
3
4
5
6
7
8
9
[root@kun05 shell]# sh -x while1.sh
+ :
++ head -1
++ awk -F 'load average: ' '{print $2}'
++ cut -d . -f1
++ w
+ load=0
+ '[' 0 -gt 10 ']'
+ sleep 30

: ture 1 都是代表为 因此while : 就是一个死循环
为了不让while脚本不意外终止 可以使用screen命令 再到screen下执行此脚本

提示让用户只能输入数字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@kun05 shell]# vim while2.sh

#!/bin/bash
while :
do
        read -p "Please input a number: " n
        if [ -z "$n" ]
        then
        echo "Please input sth!"
        continue
        fi
##判断用户是否直接回车
        n1=`echo $n|sed 's/[0-9]//g'`  
        if [ -n "$n1" ]
        then
        echo "Please input number!"
        continue
        fi
#判断用户是否输入纯数字
echo $n
break
done
1
2
3
4
5
6
7
[root@kun05 shell]# sh while2.sh
Please input a number:
Please input sth!
Please input a number: a   
Please input number!
Please input a number: 1
1

echo $n|sed 's/[0-9]//g 把数字给过滤掉来判断是否有其他字符

20.13 break跳出循环

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@kun05 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 aaaa
1
2
3
4
5
6
7
[root@kun05 shell]# sh break.sh
1
1
2
2
3
aaaa

20.14 continue结束本次循环

忽略continue之下的代码,直接进行下一次循环

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@kun05 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 aaaa
1
2
3
4
5
6
7
8
9
10
11
[root@kun05 shell]# sh continue.sh
1
1
2
2
3
4
4
5
5
aaaa

20.15 exit退出整个脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@kun05 shell]# vim exit.sh

#!/bin/bash
for i in `seq 1 5`
do
        echo $i
        if [ $i -eq 3 ]
        then
        exit 1
        fi
        echo $i
done
echo aaaa
1
2
3
4
5
6
[root@kun05 shell]# sh exit.sh
1
1
2
2
3

返回exit 后面设置的值

1
2
[root@kun05 shell]# echo $?
1

总结

  • break,continue都是在for while循环中使用的
    • break出现时候会跳出本次循环 直接忽略掉了break后面的代码
    • continue出现时候也会忽略掉了continue后面的代码并重新再来执行循环
    • exit直接跳出脚本 一般exit 后面会跟一个数字 给用户返回该值
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值