shell编程一

2019-01-07  本文已影响0人  XiaoMing丶

目录

一、shell脚本中的逻辑判断
二、文件目录属性判断
三、if特殊用法
四、case判断
五、for循环
六、while循环
七、break跳出循环
八、continue结束本次循环
九、exit退出整个脚本

一、shell脚本中的逻辑判断

[root@minglinux-01 /usr/local/sbin] a=5 
[root@minglinux-01 /usr/local/sbin] if [ $a -gt 3 ]
> then
> echo ok
> fi
ok
[root@minglinux-01 /usr/local/sbin] if [ $a -gt 3 ]; then echo ok; fi
ok
[root@minglinux-01 /usr/local/sbin] if (($a>3)); then echo ok; fi
ok
[root@minglinux-01 /usr/local/sbin] vim if1.sh

  1 #!/bin/bash
  2 a=5
  3 if [ $a -gt 3 ];then
  4     echo ok
  5 fi 

[root@minglinux-01 /usr/local/sbin] sh if1.sh 
ok
[root@minglinux-01 /usr/local/sbin] vim if2.sh

  1 #!/bin/bash
  2 a=2
  3 if [ $a -gt 3 ];then
  4     echo ok
  5 else
  6     echo no
  7 fi

[root@minglinux-01 /usr/local/sbin] sh if2.sh 
no
[root@minglinux-01 /usr/local/sbin] vim if3.sh

  1 #!/bin/bash
  2 a=3
  3 if [ $a -lt 3 ];then
  4     echo "a<3"
  5 elif [ $a -ge 3 ] && [ $a -le 6 ];then
  6     echo "a>=3 && a<=6"
  7 else
  8     echo "a<3"
  9 fi

[root@minglinux-01 /usr/local/sbin] sh if3.sh 
a>=3 && a<=6
[root@minglinux-01 /usr/local/sbin] sh -x if3.sh 
+ a=3
+ '[' 3 -lt 3 ']'
+ '[' 3 -ge 3 ']'
+ '[' 3 -le 6 ']'
+ echo 'a>=3 && a<=6'
a>=3 && a<=6

&& 表示当前一条命令成功才执行后面的命令
|| 表示当前一条命令不成功时执行后面的命令
-lt (小于)、-gt(大于)、-le(小于或等于)、-ge(大于
或等于)、-eq(等于)、-ne(不等于)

二、文件目录属性判断

shell脚本中if还经常用于判断文档的属性,if常用的选项有以下几个:

[ -f file ]判断是否是普通文件,且存在
[ -d file ] 判断是否是目录,且存在
[ -e file ] 判断文件或目录是否存在,存在为真
[ -b file ] 判断文件是块特殊文件为真
[ -c file ] 判断文件是字符特殊文件为真
[ -s file ] 判断文件大小非0时为真
[ -r file ] 判断文件是否可读,可读为真
[ -w file ] 判断文件是否可写,可写为真
[ -x file ] 判断文件是否可执行,可执行为真

[root@minglinux-01 ~] if [ -f /root/ ]; then echo ok; fi  #/root/不是文件,不显示ok
[root@minglinux-01 ~] if [ -d /root/ ]; then echo ok; fi
ok
[root@minglinux-01 ~] if [ -e /root/ ]; then echo ok; fi
ok
[root@minglinux-01 ~] if [ -e /root/a.txt ]; then echo ok; fi
[root@minglinux-01 ~] if [ -e /root/1.txt ]; then echo ok; fi
ok
[root@minglinux-01 ~] if [ -r /root/1.txt ]; then echo ok; fi
ok
[root@minglinux-01 ~] if [ -w /root/1.txt ]; then echo ok; fi
ok
[root@minglinux-01 ~] if [ -x /root/1.txt ]; then echo ok; fi
[root@minglinux-01 ~] ls -l 1.txt 
-rw-r--r--. 1 root root 2 11月  1 23:47 1.txt

三、if特殊用法

[root@minglinux-01 ~] wc -l RNG.sh 
51 RNG.sh
[root@minglinux-01 ~] a=`wc -l RNG.sh`
[root@minglinux-01 ~] if [ -z "$a" ]; then echo error; else echo $a; fi
51 RNG.sh
[root@minglinux-01 ~] if [ ! -z "$a" ]; then echo error; else echo $a; fi
error
[root@minglinux-01 ~] if [ -n "$a" ]; then echo error; else echo $a; fi
error
[root@minglinux-01 ~] if [ ! -n "$a" ]; then echo error; else echo $a; fi
51 RNG.sh

-n和-z只能作用于变量,无法作用于文件

[root@minglinux-01 ~] cat 2.txt 
c b a
3 2 1
6 5 4
[root@minglinux-01 ~] if grep -q 'a' 2.txt; then echo "Yes"; else echo "No"; fi
Yes
[root@minglinux-01 ~] if grep -q 'd' 2.txt; then echo "Yes"; else echo "No"; fi
No
[root@minglinux-01 ~] if [ ! -e ./qwer ]; then echo "不存在"; fi
不存在

四、case判断

在case程序中,可以在条件中使用|,表示或的意思,如:
2|3)
command
;;

[root@minglinux-01 /usr/local/sbin] vim case.sh
##脚本内容如下:
#!/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

[root@minglinux-01 /usr/local/sbin] sh case.sh 
Please input a number: 100
oook
[root@minglinux-01 /usr/local/sbin] sh case.sh 
Please input a number: 1
not ok
[root@minglinux-01 /usr/local/sbin] sh case.sh 
Please input a number: 
Please input a number.
[root@minglinux-01 /usr/local/sbin] sh case.sh 
Please input a number: 7897
The number range is 0-100.
[root@minglinux-01 /usr/local/sbin] echo $?
0

五、for循环

 计算1到10数字之和

[root@minglinux-01 /usr/local/sbin] vim for1.sh

  1 #!/bin/bash
  2 sum=0
  3 for i in `seq 1 10`
  4 do
  5     sum=$[$sum+$i]
  6 done
  7 echo $sum

[root@minglinux-01 /usr/local/sbin] sh -x for1.sh 
+ sum=0
++ seq 1 10
+ for i in '`seq 1 10`'
+ sum=1
+ for i in '`seq 1 10`'
+ sum=3
+ for i in '`seq 1 10`'
+ sum=6
+ for i in '`seq 1 10`'
+ sum=10
+ for i in '`seq 1 10`'
+ sum=15
+ for i in '`seq 1 10`'
+ sum=21
+ for i in '`seq 1 10`'
+ sum=28
+ for i in '`seq 1 10`'
+ sum=36
+ for i in '`seq 1 10`'
+ sum=45
+ for i in '`seq 1 10`'
+ sum=55
+ echo 55
55

[root@minglinux-01 /usr/local/sbin] vim for1.sh

  1 #!/bin/bash
  2 sum=0
  3 for i in `seq 1 10`
  4 do
  5     echo "$sum + $i"
  6     sum=$[$sum+$i]
  7     echo $sum
  8 done
  9 echo $sum

[root@minglinux-01 /usr/local/sbin] sh for1.sh 
0 + 1
1
1 + 2
3
3 + 3
6
6 + 4
10
10 + 5
15
15 + 6
21
21 + 7
28
28 + 8
36
36 + 9
45
45 + 10
55
55

 文件列表循环

[root@minglinux-01 /usr/local/sbin] vim for2.sh 

  1 #!/bin/bash
  2 cd /root/
  3 for i in `ls /root/`
  4 do
  5     if [ -d $i ]
  6     then
  7     ls -d $i
  8     fi
  9 done

[root@minglinux-01 /usr/local/sbin] sh for2.sh 
dir2
log
logs
rsync
temp

[root@minglinux-01 /usr/local/sbin] sh -x for2.sh 
+ cd /root/
++ ls /root/
+ for i in '`ls /root/`'
+ '[' -d 123.txt ']'
+ for i in '`ls /root/`'
+ '[' -d 123.tzr ']'
+ for i in '`ls /root/`'
+ '[' -d 1.txt ']'
+ for i in '`ls /root/`'
+ '[' -d 2.txt ']'
+ for i in '`ls /root/`'
+ '[' -d 3.txt ']'
+ for i in '`ls /root/`'
+ '[' -d b.txt ']'
+ for i in '`ls /root/`'
+ '[' -d cron.log ']'
+ for i in '`ls /root/`'
+ '[' -d dir2 ']'
+ ls -d dir2
dir2
+ for i in '`ls /root/`'
+ '[' -d log ']'
+ ls -d log
log
+ for i in '`ls /root/`'
+ '[' -d logs ']'
+ ls -d logs
logs
+ for i in '`ls /root/`'
+ '[' -d my.cnf ']'
+ for i in '`ls /root/`'
+ '[' -d qq.txt ']'
+ for i in '`ls /root/`'
+ '[' -d RNG.sh ']'
+ for i in '`ls /root/`'
+ '[' -d rsync ']'
+ ls -d rsync
rsync
+ for i in '`ls /root/`'
+ '[' -d sim.pid ']'
+ for i in '`ls /root/`'
+ '[' -d temp ']'
+ ls -d temp
temp
+ for i in '`ls /root/`'
+ '[' -d test.sh ']'
+ for i in '`ls /root/`'
+ '[' -d zabbix-release-3.2-1.el7.noarch.rpm ']'
#for循环时,会以空格或回车作为分隔符
[root@minglinux-01 /usr/local/sbin] mkdir test
[root@minglinux-01 /usr/local/sbin] cd test
[root@minglinux-01 /usr/local/sbin/test] touch 1 2 a\ b 
[root@minglinux-01 /usr/local/sbin/test] ls -l
总用量 0
-rw-r--r-- 1 root root 0 1月   4 20:22 1
-rw-r--r-- 1 root root 0 1月   4 20:22 2
-rw-r--r-- 1 root root 0 1月   4 20:22 a b
[root@minglinux-01 /usr/local/sbin/test] for i in `ls ./`; do echo $i; done
1
2
a
b
#a空格b是一个文件,for循环却将a b拆成a、b两个对象

六、while循环

案例一
需求:每隔半分钟检查一次系统的负载,当系统负载大于10时,发一封邮件给管理员

[root@minglinux-01 ~] w
 17:31:33 up 1 day, 21:05,  2 users,  load average: 0.00, 0.01, 0.05
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/1    192.168.162.1    16:14    1:09m  0.40s  0.15s vim while1.s
root     pts/2    192.168.162.1    16:22    5.00s  0.15s  0.01s w
[root@minglinux-01 ~] uptime
 17:31:47 up 1 day, 21:05,  2 users,  load average: 0.00, 0.01, 0.05
[root@minglinux-01 ~] w |head -1|awk -F 'load average: ' '{print $2}'|cut -d . -f1
0
[root@minglinux-01 ~] uptime|awk -F 'load average: ' '{print $2}'|cut -d . -f1
0

##编写监控脚本如下
[root@minglinux-01 /usr/local/sbin] vim while1.sh

  1 #!/bin/bash
  2 while true  ##使用true和:(冒号)都表示真,进入无限循环
  3 do
  4     load=`w|head -1|awk -F 'load average: ' '{print $2} `
  1 #!/bin/bash
  2 while true
  2 while true
  3 do
  4     load=`w|head -1|awk -F 'load average: ' '{print $2}'|cut -d . -f1`
  5     if [$load -gt 10]
  6     then
  7         /usr/local/sbin/mail.py 331601950@qq.com "load high" "$load"
  8     fi
  9     sleep 30
 10 done
##执行脚本
[root@minglinux-01 /usr/local/sbin] sh -x while1.sh 
+ true
++ w  ##第一次
++ head -1
++ awk -F 'load average: ' '{print $2}'
++ cut -d . -f1
+ load=0
+ '[' 0 -gt 10 ']'
+ sleep 30
+ true
++ w  ##第二次
++ head -1
++ awk -F 'load average: ' '{print $2}'
++ cut -d . -f1
+ load=0
+ '[' 0 -gt 10 ']'
+ sleep 30
···
···

若不想让脚本出现意外终止,可以在screen中运行脚本

案例二
需求:交互方式输入数字,根据输入数字判断后打印输出

[root@minglinux-01 /usr/local/sbin] cat while2.sh 
#!/bin/bash
while :
do 
    read -p "请输入一个数字: " n
    if [ -z "$n" ]
    then 
        echo "你需要输入东西"
        continue
    fi
    n1=`echo $n|sed 's/[0-9]//g'`
    if [ ! -z $n1 ]
    then 
        echo "你只能输入一个纯数字"
        continue
    fi 
    break
done
echo $n

[root@minglinux-01 /usr/local/sbin] sh while2.sh 
请输入一个数字: 
你需要输入东西
请输入一个数字: 12a
你只能输入一个纯数字
请输入一个数字: 123
123

七、break跳出循环

[root@minglinux-01 /usr/local/sbin] cat break.sh 
#!/bin/bash
for i in `seq 1 5`
do 
    echo $i
    if [ $i -eq 2 ]   ##数字间比较时使用-eq/-lt/-gt等,字符时比较使用==
    then
        break
    fi 
    echo $i
done
echo "ok"
[root@minglinux-01 /usr/local/sbin] sh break.sh 
1
1
2
ok

八、continue结束本次循环

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

[root@minglinux-01 /usr/local/sbin] cat continue.sh 
#!/bin/bash
for i in `seq 1 5`
do 
    echo $i
    if [ $i -eq 2 ]
    then
        continue 
    fi 
    echo $i
done
echo "ok"
[root@minglinux-01 /usr/local/sbin] sh continue.sh 
1
1
2
3
3
4
4
5
5
ok

九、exit退出整个脚本

[root@minglinux-01 /usr/local/sbin] cat exit.sh 
#!/bin/bash
for i in `seq 1 5`
do 
    echo $i
    if [ $i == 2 ]
    then
        exit
    fi 
    echo $i
done
echo "ok"
[root@minglinux-01 /usr/local/sbin] sh exit.sh 
1
1
2

##通常exit执行后会返回一个状态码,该状态码可自定义,如下
[root@minglinux-01 /usr/local/sbin] cat exit.sh 
#!/bin/bash
for i in `seq 1 5`
do 
    echo $i
    if [ $i == 2 ]
    then
        exit 1
    fi 
    echo $i
done
echo "ok"
[root@minglinux-01 /usr/local/sbin] sh exit.sh 
1
1
2
[root@minglinux-01 /usr/local/sbin] echo $?
1
上一篇下一篇

猜你喜欢

热点阅读