第三十一课预习笔记--Shell(1)

20.1 Shell脚本介绍

  • shell是一种脚本语言
  • 可以使用逻辑判断、循环等语法
  • 可以自定义函数
  • shell是系统命令的集合
  • shell脚本可以实现自动化运维,能大大增加我们的运维效率
  • 解决日常运维工作中的重复工作

 

20.2 Shell脚本结构和执行

shell脚本结构和执行方法

  • 开头需要加#!/bin/bash,在本机上省略了能够执行,但是换一个机器就不一定能行了
  • 以#开头的行作为解释说明
  • 脚本的名字以.sh结尾,用于区分这是一个shell脚本
  • 执行方法有两种
  • chmod a+x 1.sh; ./1.sh
  • bash 1.sh
  • 查看脚本执行过程 bash -x 1.sh
  • 查看脚本是否语法错误  bash -n 1.sh

1、简单shell脚本

#!/bin/bash
echo 123
w
ls

在本机上省略#!/bin/bash

echo 123
w
ls

执行sh 1.sh,是能够执行的,但是换一个机器就不一定能行了。

[root@liang-00 shell]# sh 1.sh 
123
 17:06:38 up  6:02,  1 user,  load average: 0.00, 0.01, 0.05
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    192.168.37.1     16:42    6.00s  2.00s  0.01s w
1.sh
[root@liang-00 shell]# 

#!/bin/bash意思是说下面的脚本时能够让/bin/bash解析的。

加上 #!/bin/bash 给1.sh赋予x权限:chmod a+x 1.sh 后才能够直接执行。

[root@liang-00 shell]# chmod a+x 1.sh 
[root@liang-00 shell]# ./1.sh 
123
 17:11:50 up  6:07,  1 user,  load average: 0.00, 0.01, 0.05
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    192.168.37.1     16:42    6.00s  2.07s  0.00s /bin/bash ./1.sh
1.sh
[root@liang-00 shell]# 

2、其实 /bin/bash和/bin/sh 是同一个文件

[root@liang-00 shell]# ll /bin/bash
-rwxr-xr-x. 1 root root 964544 Apr 11  2018 /bin/bash
[root@liang-00 shell]# which sh
/usr/bin/sh
[root@liang-00 shell]# ll /bin/sh
lrwxrwxrwx. 1 root root 4 Oct 16 18:00 /bin/sh -> bash
[root@liang-00 shell]# 

#!/bin/bash放在第一行才表示用/bin/bash解析,以后的#开头的表示解释说明。

3、sh -x 1.sh 表示查看脚本执行过程,每个“+”表示一个步骤。

[root@liang-00 shell]# sh -x 1.sh 
+ echo 123
123
+ w
 17:20:19 up  6:16,  1 user,  load average: 0.00, 0.01, 0.05
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    192.168.37.1     16:42    3.00s  2.48s  0.01s w
+ ls
1.sh
[root@liang-00 shell]# 

4、sh -n 1.sh 查看脚本语法是否有错误。

 

20.3 date命令用法

date命令在shell脚本中作用很大。标记和更改文件,加上日期标记。

1、日期时间标记。

+%Y:四位的年2018

+%y:两位的年18

+%m:月份

+%M:分钟

+%d:日期

+%D:标记一个年月日(01/08/19)

+%F:带“-”的年月日

+%H:小时

+%S:秒

+%s:表示时间戳,距离1970年1月1日多长时间,单位秒。

+%T:等于+%H:%M:%S

+%w:星期几

+%W:今年的第几周

cal:以日历的格式查看日期

cal命令,日历格式显示

[root@liang-00 shell]# cal
    January 2019    
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

[root@liang-00 shell]# 

date -d “-1 day”     一天前,具体的还有month、year、hour、min、sec等。

[root@liang-00 shell]# date -d "-1 day" 
Mon Jan  7 17:48:13 CST 2019
[root@liang-00 shell]# date -d "-1 month" 
Sat Dec  8 17:48:23 CST 2018
[root@liang-00 shell]# date -d "-1 year" 
Mon Jan  8 17:48:28 CST 2018
[root@liang-00 shell]# date -d "-1 hour" 
Tue Jan  8 16:48:47 CST 2019
[root@liang-00 shell]# date -d "-1 min" 
Tue Jan  8 17:48:03 CST 2019
[root@liang-00 shell]# date -d "-1 sec" 
Tue Jan  8 17:49:29 CST 2019
[root@liang-00 shell]# 

date -d +%s 时间戳

date -d @1546941077    时间戳和具体日期换算(把时间戳转换成具体时间)。

date +%s -d “2019-1-8 17:51:17”    把具体的时间转换成相应的时间戳。

[root@liang-00 shell]# date +%s
1546941077
[root@liang-00 shell]# date -d @1546941077
Tue Jan  8 17:51:17 CST 2019
[root@liang-00 shell]# date  +%s -d "2019-1-8 17:51:17"
1546941077
[root@liang-00 shell]# 

 

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
  • 格式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

1、if的第一种格式if then。

命令行写出。

[root@liang-00 shell]# a=4
[root@liang-00 shell]# if [ $a -gt 3 ]
> then
> echo OK
> fi
OK
[root@liang-00 shell]# if [ $a -gt 3 ]; then echo OK; fi
OK
[root@liang-00 shell]#  

在 if 这种格式或 shell 中每个参数之间都要有“空格”。

在shell脚本中表示。

[root@liang-00 shell]# vi if_1.sh
[root@liang-00 shell]# cat if_1.sh 
#!/bin/bash
a=4
if [ $a -gt 3 ]
then
    echo OK
fi
[root@liang-00 shell]# sh if_1.sh 
OK

2、else(注意空格)

[root@liang-00 shell]# cat if_1.sh 
#!/bin/bash
a=1
if [ $a -gt 3 ]
then
    echo OK
else
    echo not OK
fi
[root@liang-00 shell]# sh -x if_1.sh 
+ a=1
+ '[' 1 -gt 3 ']'
+ echo not OK
not OK
[root@liang-00 shell]# 

3、elif(注意空格)

[root@liang-00 shell]# cat if_1.sh 
#!/bin/bash
a=1
if [ $a -gt 3 ]
then
    echo "a>3"
elif [ $a -gt 0 ]
then
    echo "3>a>0"
else
    echo "a<0"
fi
[root@liang-00 shell]# sh -x if_1.sh 
+ a=1
+ '[' 1 -gt 3 ']'
+ '[' 1 -gt 0 ']'
+ echo '3>a>0'
3>a>0
[root@liang-00 shell]# 

4、&& 表示并且,|| 表示或者

[root@liang-00 shell]# sh -x if_2.sh 
+ a=6
+ '[' 6 -gt 0 ']'
+ '[' 6 -lt 5 ']'
+ echo 'a>=5'
a>=5
[root@liang-00 shell]# cat if_2.sh 
#!/bin/bash
a=6
if [ $a -gt 0 ] && [ $a -lt 5 ]
then 
    echo "5>a>0"
else
    echo "a>=5"
fi
[root@liang-00 shell]# 

 

 

20.6 文件目录属性判断

  • [ -f file ]判断是否是普通文件,且存在
  • [ -d file ] 判断是否是目录,且存在
  • [ -e file ] 判断文件或目录是否存在
  • [ -r file ] 判断文件是否可读
  • [ -w file ] 判断文件是否可写
  • [ -x file ] 判断文件是否可执行

1、shell脚本判断一个文件是否存在

[root@liang-00 shell]# sh -x file_1.sh 
+ f=/tmp/testfile
+ '[' -f /tmp/testfile ']'
+ touch /tmp/testfile
[root@liang-00 shell]# cat file_1.sh 
#!/bin/bash
f="/tmp/testfile"
if [ -f $f ]
then
    echo $f
else
    touch $f
fi
[root@liang-00 shell]# 

是否为命目录。

[root@liang-00 shell]# vi file_1.sh 
[root@liang-00 shell]# sh -x file_1.sh 
+ f=/tmp/testfile
+ '[' -d /tmp/testfile ']'
+ touch /tmp/testfile

是否存在。

[root@liang-00 shell]# vi file_1.sh 
[root@liang-00 shell]# sh -x file_1.sh 
+ f=/tmp/testfile
+ '[' -e /tmp/testfile ']'
+ echo /tmp/testfile
/tmp/testfile
[root@liang-00 shell]# 

用&&来执行命令:

f="/tmp/testfile"

[ -f $f ] && rm -f $f 等同于

if [ -f $f ]

then

    rm -f $f

fi

判断文件不存在用"!"。

 [ ! -f $f ] && rm -f $f

 

20.7 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… 
  • [ ] 中不能使用<,>,==,!=,>=,<=这样的符号

1、判断变量为空时

#!/bin/bash
n=`wc -l /tmp/aaa`
if [ -z "$n" ]
then
    echo "n not exist."
    exit
elif [ $n -gt 100 ]
then
    echo "ssssssss"
fi

改良,先判断文件是否存在

if [ ! -f /tmp/aaa ]
then
    echo "/tmp/aaa not exist."
    exit
fi
n=`wc -l /tmp/aaa`
if [ $n -gt 100 ]
then
    echo "ssssssss"
fi

2、判断不为空 if [ -n "$a" ]

[root@liang-00 shell]# echo $b

[root@liang-00 shell]# if [ -n "$b" ];then echo $b;else echo "b is null";fi
b is null
[root@liang-00 shell]# 

3、if grep 用法

[root@liang-00 shell]# if grep -wq 'liang' /etc/passwd ;then echo "liang is exist";fi
liang is exist
[root@liang-00 shell]# if ! grep -wq 'liang' /etc/passwd ;then useradd liang;fi
[root@liang-00 shell]# 

-w表示匹配只单词,-q表示只执行不输出内容

 

20.8 case判断

格式 case  变量名 in                    
                         value1)                          
                                 command                          
                                 ;;                    
                         value2)                        
                                 command                        
                                 ;;                  
                         *)                       
                                 commond                           
                                 ;;                   
                         esac

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

2|3)

    command

    ;;

1、shell脚本案例,考试成绩判断:

#!/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 "not ok"
        ;;
    2)
        echo "ok"
        ;;
    3)
        echo "ook"
        ;;
    4)
        echo "oook"
        ;;
    *)
        echo "The number range is 0-100."
        ;; 
esac

read -p "Please input your mark: " n 获得一个用户输入的值,赋予n

[root@liang-00 shell]# read -p "Please input your mark: " n
Please input your mark: 90
[root@liang-00 shell]# echo $n
90
[root@liang-00 shell]#

exit 1 表示执行完命令后退出的状态。

[root@liang-00 shell]# sh test.sh
Please input a number: 
Please input a number.
[root@liang-00 shell]# echo $?
1
[root@liang-00 shell]# cat test.sh 
#!/bin/bash
read -p "Please input a number: " n
if [ -z "$n" ]
then
    echo "Please input a number."
    exit 1
fi
[root@liang-00 shell]# 

执行shell脚本

[root@liang-00 shell]# sh -x case.sh 
+ read -p 'Please input a number: ' n
Please input a number: 90
+ '[' -z 90 ']'
++ sed 's/[0-9]//g'
++ echo 90
+ n1=
+ '[' -n '' ']'
+ '[' 90 -lt 60 ']'
+ '[' 90 -ge 60 ']'
+ '[' 90 -lt 80 ']'
+ '[' 90 -ge 80 ']'
+ '[' 90 -lt 90 ']'
+ '[' 90 -ge 90 ']'
+ '[' 90 -le 100 ']'
+ tag=4
+ case $tag in
+ echo oook
oook
[root@liang-00 shell]# sh -x case.sh 
+ read -p 'Please input a number: ' n
Please input a number: 80
+ '[' -z 80 ']'
++ echo 80
++ sed 's/[0-9]//g'
+ n1=
+ '[' -n '' ']'
+ '[' 80 -lt 60 ']'
+ '[' 80 -ge 60 ']'
+ '[' 80 -lt 80 ']'
+ '[' 80 -ge 80 ']'
+ '[' 80 -lt 90 ']'
+ tag=3
+ case $tag in
+ echo ook
ook
[root@liang-00 shell]# sh -x case.sh 
+ read -p 'Please input a number: ' n
Please input a number: 101
+ '[' -z 101 ']'
++ echo 101
++ sed 's/[0-9]//g'
+ n1=
+ '[' -n '' ']'
+ '[' 101 -lt 60 ']'
+ '[' 101 -ge 60 ']'
+ '[' 101 -lt 80 ']'
+ '[' 101 -ge 80 ']'
+ '[' 101 -lt 90 ']'
+ '[' 101 -ge 90 ']'
+ '[' 101 -le 100 ']'
+ tag=0
+ case $tag in
+ echo 'The number range is 0-100.'
The number range is 0-100.
[root@liang-00 shell]# sh -x case.sh 
+ read -p 'Please input a number: ' n
Please input a number: sa
+ '[' -z sa ']'
++ sed 's/[0-9]//g'
++ echo sa
+ n1=sa
+ '[' -n sa ']'
+ echo 'Please input a number.'
Please input a number.
+ exit 1
[root@liang-00 shell]# 

 

20.10 for循环

  • 语法:for 变量名 in 条件; do …; done
  • 案例1:求和1-100

#!/bin/bash
sum=0
for i in `seq 1 100`
do
    sum=$[$sum+$i]
    echo $i
done
echo $sum

1、数字求和。

首先实现打印出1-100

#!/bin/bash
for i in `seq 1 100`
do
    echo $i
done
~     

再求1-100的和,最后打印出总和。

#!/bin/bash
sum=0
for i in `seq 1 100`
do
    sum=$[$sum+$i]
done
echo $sum

seq命令:用于产生从某个数到另外一个数之间的所有整数。

[root@liang-00 shell]# seq 1 10
1
2
3
4
5
6
7
8
9
10
[root@liang-00 shell]# seq 1 10 |xargs
1 2 3 4 5 6 7 8 9 10
[root@liang-00 shell]# 

2、对文件目录for循环。

进入/etc目录,遍历etc下的内容,如果是目录的话,只列出该目录。

#!/bin/bash
cd /etc/   先进入到目录下在for循环
for a in `ls /etc/`
do
    if [ -d $a ]
    then
       ls -d $a
    fi
done

执行脚本

[root@liang-00 shell]# sh for2.sh
alternatives
audisp
audit
bash_completion.d
binfmt.d
chkconfig.d
cron.d
cron.daily
cron.hourly
cron.monthly
cron.weekly
dbus-1
default
depmod.d
dhcp
dnsmasq.d
dracut.conf.d
exports.d
firewalld
fonts
...............

3、for在遍历的时候是以回车符或空格来分割元素的,所以文件名字中有空格的情况下,for会把文件识别错

例如:“3 4.txt”是一个文件,在做for循环遍历是会把它当做两个文件来处理。

[root@liang-00 liang]# touch 1 2 3\ 4.txt
[root@liang-00 liang]# ll
total 0
-rw-r--r-- 1 root root 0 Jan  9 00:04 1
-rw-r--r-- 1 root root 0 Jan  9 00:04 2
-rw-r--r-- 1 root root 0 Jan  9 00:04 3 4.txt
[root@liang-00 liang]# for i in `ls` ;do echo $i ;done
1
2
3
4.txt
[root@liang-00 liang]# 

 

20.11 while循环

  • 语法 while 条件; do … ; done

案例1:每隔半分钟检查下负载,当系统负载大于10时发送邮件。

#!/bin/bash
while :
do
    load=`uptime|awk -F 'load average: ' '{print $2}'|cut -d. -f1`
    if [ $load -gt 10 ]
    then
        top|mail -s "load is high: $load" asldkfls@11.com
    fi
    sleep 30
done

其中:while后的冒号表示死循环,还可以是true,也表示死循环。

[root@liang-00 liang]# sh -x while1.sh 
+ true
++ uptime
++ awk -F 'load average: ' '{print $2}'
++ cut -d. -f1
+ load=0
+ '[' 0 -gt 10 ']'
+ sleep 30

为了不让脚本意外终止,可以打开一个screen,在screen里执行。

案例2:得到想要的结果在退出循环。

#!/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

执行脚本:

[root@liang-00 shell]# sh while2.sh 
Please input a number: www1111111
you just only input numbers.
Please input a number: 2222222222222111111111111111
2222222222222111111111111111
[root@liang-00 shell]# 

 

20.13 break跳出循环

在for循环中用break

#!/bin/bash
for i in `seq 1 5`
do
    echo $i
    if [ $i -eq 3 ]
    then
        break
    fi
    echo $i
done
echo aaaaaaa

执行脚本:

[root@liang-00 shell]# sh for_break.sh 
1
1
2
2
3
aaaaaaaaaaaa
[root@liang-00 shell]# 

 

20.14 continue结束本次循环

  • 忽略continue之下的代码,直接进行下一次循环
#!/bin/bash
for i in `seq 1 5`
do
    echo $i
    if [ $i == 3 ]
    then
        continue
    fi
    echo $i
done
echo $i

执行脚本:

[root@liang-00 shell]# sh for_break.sh 
1
1
2
2
3
4
4
5
5
5
[root@liang-00 shell]# 

 

20.15 exit退出整个脚本

#!/bin/bash
for i in `seq 1 5`
do
    echo $i
    if [ $i == 3 ]
    then
        exit
    fi
    echo $i
done
echo aaaaaaa

执行脚本:

[root@liang-00 shell]# sh for_break.sh 
1
1
2
2
3
[root@liang-00 shell]# 

 

扩展:

select用法:http://www.apelearn.com/bbs/thread-7950-1-1.html

 

转载于:https://my.oschina.net/u/3993922/blog/2999002

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值