8月25日 脚本进阶2

1、while循环

while CONDITION; do
循环体
done
CONDITION:循环控制条件;进入循环之前,先做一次判断;每一次循环之后会再次做判断;条件为“true”,则执行一次循环;直到条件测试状态为“false”终止循环
因此:CONDTION一般应该有循环控制变量;而此变量的值会在循环体不断地被修正
进入条件:CONDITION为true
退出条件:CONDITION为false
举例

#!/bin/bash
sum=0
i=1
while [ $i -le 100 ];do  ---先进行判断,如果为真,则执行循环体
    let sum+=i   ---表示sum=sum+i
    let i++      ---表示i=i+1
done
      echo sum is $sum
[root@redhat7 app]#i=0;let i++;echo $?   ---i++表示先赋值再相加,此时i=0,规定如果let后的值是零,则退出状态码为1
1
[root@redhat7 app]#i=0;let ++i;echo $?---表示先相加再赋值,此时let后的值是1
0

总结:要引起注意,两个返回的值不一样,不小心可能会出错,因为while进行判断时真就进行循环,假就退出循环。

#!/bin/bash
read -p "please input nework(eg:192.168.0.0): " network
      netid=`echo $network|cut -d. -f1-3` ---取出网络id位并定义为变量
      hostid=1
      up=0
      down=0
      while [ $hostid -le 254 ];do
     if  ping -c1 -w1 $netid.$hostid &>/dev/null;then ---pingIP地址
         echo "the $netid.$hostid is up"  ---如果成功则打印ip地址是up
                 let up++   ---并且让up增加一个
     else
         echo "the $netid.$hostid is down"
                   let down++
    fi
                        let hostid++

    done
            echo up host is $up
            echo down host is $down

如何实现死循环

[root@redhat7 app]#while true;do echo xxx;sleep 1;done  ---while 后
面的条件如果一直是真,则不会退出循环体,就会一直循环,实现死
循环。
xxx
xxx
[root@redhat7 app]#true   ---true的值返回的总是真,可以实现死循环
[root@redhat7 app]#echo $?
0

实现每5秒钟监控一下http这个服务是否正常运行,如果不正常运行,就重启服务,并写进日志

#!/bin/bash
while true;do  ---实现死循环
  if killall -0 httpd &>/dev/null;then   ---监控httpd服务是否正常运行,发0信号就可以监控
         echo the htttpd service is normal
 else
        systemctl restart httpd&>/dev/null
        echo "`date '+%F %T'` restart httpd " >>/app/httpd.log  ---将什
么时间重启的服务写进日志
 fi
     sleep 5  ---睡眠5秒后继续执行循环体
done

用while循环实现国际象棋

#!/bin/bash
i=1
 while [ $i -le 8 ];do
    j=1
   while [ $j -le 8 ];do
    let flag=i+j
   if [ $[flag%2] -eq 0 ];then  ---表示进行算术运行,还可以写成
$(flag%2)= $[flag%2],表示取余数的意思,能被2整除就是偶数。
        echo -ne "\033[41m  \033[0m"
   else
        echo -ne "\e[43m  \e[0m"
   fi
          let j++
   done
      echo 
        let i++
 done
Paste_Image.png

总结:国际象棋的特点是八行八列,最外面的while循环打印八行,里面的whlie循环打印八列,其中行号加列号为偶数的是一种背景色,是奇数的为另外一种背景色,根据这个特点可以规定什么时候打印什么背景色。

2、until循环

until CONDITION; do
循环体
done
进入条件:CONDITION 为false
退出条件:CONDITION 为true
总结:until循环和while循环的格式相同,但判断时是假才进入循环体,和while循环正好相反。

3、循环控制语句continue

用于循环体中
continue [N]:提前结束第N层的本轮循环,而直接进入下一轮判断;最内层为第1层

#!/bin/bash
i=1
 while [ $i -le 10 ];do
     [ $i -eq 5 ]&&continue  ---结束本轮循环,而不是退出整个循环
     echo i=$i
     let i++
done
[root@redhat7 app]#./continue.sh --执行到5的时候,就结束本轮循
环,i也不会加1,此时1一直都是5,页不会打印,因为打印是在
continue后面,就会一直停着,也不会退出。
i=1
i=2
i=3
i=4
#!/bin/bash
i=0
 while [ $i -le 10 ];do
     let i++
   if  [ $i -eq 5 ];then
       continue
   else
     echo i=$i
   fi
done
执行结果
[root@redhat7 app]#./continue.sh ---当遇到5时就结束本轮循环,不
进行打印5
i=1
i=2
i=3
i=4
i=6
i=7
i=8
i=9
i=10
i=11

4、循环控制语句break

用于循环体中
break [N]:提前结束第N层循环,最内层为第1层

#!/bin/bash
i=0
 while [ $i -le 10 ];do
     let i++
   if  [ $i -eq 5 ];then
       break
   else
     echo i=$i
   fi
done
执行情况
[root@redhat7 app]#./break.sh 
i=1
i=2
i=3
i=4

continue和break的区别:后面不加数字的时候默认都是第1层,也就是最内层,continue是结束第1层的本轮循环,而break是结束第1层循环,比如第一层有10个循环,continue只是结束本层的第几个循环,而break是跳出本层的整个循环。

for i in {1..10};do
  for j in {1..10};do
      echo -n "$j "
  [ $j -eq 5 ]&&continue 2  ---表示当j=5时就跳出第2层也就是最外面层的某一次循环,进行下一次循环,所以不会执行echo换行。
  done
      echo 
  done
[root@redhat7 app]#./continue.sh 
1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5
2 3 4 5 1 2 3 4 5 [root@redhat7 app]#vim continue.sh 
#!/bin/bash
for i in {1..10};do
  for j in {1..10};do
      echo -n "$j "
  [ $j -eq 5 ]&&break 2  ---表示当j=2时跳出整个最外层的循环
     done
      echo 
done
[root@redhat7 app]#./continue.sh 
1 2 3 4 5

5、循环控制shift命令

shift [n]
用于将参量列表list 左移指定次数,缺省为左移一次。
参量列表list 一旦被移动,最左端的那个参数就从列表中删除。while 循环遍历位置参量列表时,常用到shift

举例

#!/bin/bash
while [ $# -gt 0 ];do
    echo $*
   shift
    done
[root@redhat7 app]#./shift.sh a b c d e f 
a b c d e f
b c d e f
c d e f
d e f
e f
f
#!/bin/bash
while [ $# -gt 0 ];do
     id $1 &>/dev/null && continue
     useradd $1 &>/dev/null && echo $1 is created
   shift   ---如果不加shift,始终都是第一个参数,就创建不了其他的
用户了
done
[root@redhat7 app]#./shiftuser.sh lixinru fanbingbing lixiaolu
lixinru is created
fanbingbing is created
lixiaolu is created

6、特殊用法

  • while和read配合使用可以依次处理文件或命令的每一行

while循环的特殊用法(遍历文件的每一行):
while read line; do
循环体
done < /PATH/FROM/SOMEFILE
依次读取/PATH/FROM/SOMEFILE文件中的每一行,且将行赋值给变量line
read 等待读取键盘输入,可以用管道,将命令的执行结果逐行的赋值给read定义的变量

举例

扫描/etc/passwd文件每一行,如发现描述信息字段为空,则填充用户
名和单位电话为62985600,并提示该用户的描述信息修改成功。
#!/bin/bash
while read line;do
   gecons=`echo $line |cut -d: -f5`
   username=`echo $line |cut -d: -f1`
   if [ -z $gecons ];then  ---表示空为真,空就执行下面的操作,[ -n $gecons ]正好相反,表示非空为真
       chfn -f $username -p 62985600 $username &>/dev/null  ---chfn
命令可以修改用户的描述信息,其中-f选项是添加描述信息中的用户名,
-p选项是添加单位电话
         echo the $username finger is modify
   fi
    done < /etc/passwd   ---逐行的读取这个文件中的每一行赋值给line

也可以用管道

检查分区利用率,发现80%就报警,并且指出设备名
#!/bin/bash
df|grep '/dev/sd'|while read disk;do
           diskused=`echo $disk|sed -r 's/^.* ([0-9]{1,2})%.*$/\1/'`
           devname=`echo $disk|cut -d ' ' -f1`
         [ $diskused -gt 80 ]&& echo "$devname will be full:$diskused%"
done
  • 双小括号用法

双小括号方法,即((…))格式,也可以用于算术运算
for循环的特殊格式:
for ((控制变量初始化;条件判断表达式;控制变量的修正表达式))
do
循环体
done
控制变量初始化:仅在运行到循环代码段时执行一次
控制变量的修正表达式:每轮循环结束会先进行控制变量修正运算,而后再做条件判断

QQ截图20170826140313.png

举例

#!/bin/bash
for ((i=1,sum=0;i<=100;i++));do  ---执行时,控制变量的初始化就刚开始时执行一次,然后进行判断,进入第一次循环,循环结束之后,进行变量的修正,让i增加1,然后再进行判断,进入第二轮循环
    let sum+=i
done
   echo "sum=$sum"
#!/bin/bash
sum=0
i=1
while ((i<=100));do
     let sum+=i
     let i++
done
    echo "sum=$sum"

7、select循环与菜单

select variable in list
do
循环体命令
done
select 循环主要用于创建菜单,按数字顺序排列的菜单项将显示在标准错误上,并显示PS3 提示符,等待用户输入
用户输入菜单列表中的某个数字,执行相应的命令
用户输入被保存在内置变量REPLY 中
举例

[root@redhat7 script]#select menus in lamian huimian yangtangmian yangroutang;do echo $menus;done
1) lamian
2) huimian
3) yangtangmian
4) yangroutang
#? 1    --输入菜单中的某个数字,执行do之后的命令
lamian
#? 
PS3=‘please choose your menu: '可以修改PS3提示符
[root@redhat7 script]#select menus in lamian huimian yangtangmian yangroutang;do echo $menus;done
1) lamian
2) huimian
3) yangtangmian
4) yangroutang
please choose your menu : 1
lamian
please choose your menu : 2
huimian
please choose your menu : 3
yangtangmian
please choose your menu : 4
yangroutang
please choose your menu : 1
lamian
please choose your menu : ---可以发现select循环是个无限循环,不会退出
编写脚本实现点菜功能
#!/bin/bash
PS3='please choose your menu:'
select menu in lamimian huimian yangtangmian yangroutang yangpai;do ----用户输入菜单对应的数字,会执行do循环体内的命令
case $REPLY in       ----用户的输入的数字被保存到REPLY变量中
1)
     echo "price is \$10"
         ;;
2)
     echo "price is \$15"
          ;;
3)
   echo "price is \$25"
       ;;
4)   echo "price is \$40"
        ;;
5)     echo "price is \$50"
                   ;;
*)     echo "get out!"
          break
esac
done

总结:select 是个无限循环,因此要记住用break 命令退出循环,或用exit 命令终止脚本。也可以按ctrl+c 退出循环,select 经常和case 联合使用。
PS1命令提示符
PS2多行重定向的命令提示符

8、信号捕捉trap

trap '触发指令' 信号
自定义进程收到系统发出的指定信号后,将执行触发指令,而不会执行原操作
trap ' ' 信号:忽略信号的操作
trap '-' 信号:恢复原信号的操作
trap -p:列出自定义信号操作
trap -l:查看都有哪些信号
举例

[root@redhat7 script]#trap -l  ---查看信号,2信号表示ctrl+c
 1) SIGHUP   2) SIGINT   3) SIGQUIT  4) SIGILL   5) SIGTRAP
 6) SIGABRT  7) SIGBUS   8) SIGFPE   9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG  24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF 28) SIGWINCH    29) SIGIO   30) SIGPWR
31) SIGSYS  34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX    
#!/bin/bash
trap 'echo "you are a baby"' int   ---注意int前面一定要有空格,这是一个坑,没有空格脚本执行有错误,并且单引号里面要放命令,意思是执行这个信号后会执行什么命令
    trap -p    ---列出自定义的信号
for ((i=1;i<10;i++));do
      echo $i  
       sleep 0.5
done
[root@redhat7 script]#./trap.sh 
trap --'echo "you are a baby"' SIGINT  ---显示出自定义的信号
1
2
^Cpress ctrl+c  ---原来按ctrl+c时就终止这个脚本,此时按ctrl+c不起
作用,不会终止脚本,而是在屏幕上打印一句话。
3
4
^Cyou are a baby
5
6
^Cyou are a baby
7
8
^Cyou are a baby
9
#!/bin/bash
trap '' int  ---双引号中间什么也没有表示忽略信号的操作,当你按ctrl+c时,不会停止脚本的运行
for ((i=1;i<10;i++));do
      echo $i  
       sleep 1
done
#!/bin/bash
trap '-' int    ---双引号中间放个-表示恢复信号的操作,此时再按ctrl+c就可以停止脚本了
for ((i=1;i<10;i++));do
      echo $i  
       sleep 1
done
#!/bin/bash
trap 'echo nozuonodi' term  ---换一个信号,15信号是杀死进程,信号的名字是sigterm,大小写都可以,也可以简写为term
trap -p
for ((i=1;i<100;i++));do
      echo $i  
       sleep 1
done
killall trap.sh    当执行这个命令时,原操作是会杀死进程,现在不可
以了,而是在屏幕上打印一句话nozuonodi
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容

  • 选择执行:if语句条件判断:case语句循环控制:for语句循环控制:while语句和until语句循环控制:co...
    哈喽别样阅读 396评论 0 1
  • 流程控制过程式编程语言:顺序执行选择执行循环执行 一.条件选择if语句 类型:选择执行 注意:if语句可嵌套 ...
    楠人帮阅读 483评论 0 1
  • linux资料总章2.1 1.0写的不好抱歉 但是2.0已经改了很多 但是错误还是无法避免 以后资料会慢慢更新 大...
    数据革命阅读 12,149评论 2 34
  • 一个简单的搜索引擎 该搜索引擎具有以下功能:通过一个种子链接不断爬取网页,可以指定爬取网页的层数,以此来控制搜索的...
    丁昆朋阅读 282评论 0 0
  • 尊敬的各位领导,各位老师,各位家长,亲爱的同学们,大家好!今天我发言的题目是《争做博雅教师,打造精品课堂,培养博...
    Yeah明珠阅读 1,078评论 2 0