shell脚本进阶一(for,while,continue,break,select等等)
脚本进阶一
一、for循环的第二种写法: 众所周知,for有两种写法
直接写怎么用: #for后必须写两个括号,又称双小括号写法 [[email?protected] ~]# cat for_2.sh #!/bin/bash for ((i=1,sum=0;i<=100;i++));do let sum+=i done echo "sum=${sum}" [[email?protected] ~]# bash for_2.sh sum=5050 二、while循环 我喜欢这样写,一直循环然后用break退出 [[email?protected] ~]# cat while_sum.sh #!/bin/bash i=1 sum=0 while true;do let sum+=i let i++ if [ $i -gt 100 ];then break fi done echo "sum=${sum}" [[email?protected] ~]# bash while_sum.sh sum=5050 while的高级用法:读取标准输入的内容实现循环 [[email?protected] ~]# cat while_2.sh #!/bin/bash while read line do echo $line done < /etc/fstab [[email?protected] ~]# bash while_2.sh # # /etc/fstab # Created by anaconda on Thu Aug 8 19:04:39 2019 # # Accessible filesystems,by reference,are maintained under ‘/dev/disk‘ # See man pages fstab(5),findfs(8),mount(8) and/or blkid(8) for more info # /dev/mapper/centos-root / xfs defaults 0 0 UUID=3778e6e0-8f51-4843-8b8f-239c8b5e826b /boot xfs defaults 0 0 /dev/mapper/centos-home /home xfs defaults 0 0 /dev/mapper/centos-swap swap swap defaults 0 0 并且看网友的资料说,上面写法中wile使用重定向机制,fstab文件内容被重定向给了整个while语句,这个特性要注意下 while的注意事项1:管道传递内容:echo "abc xyz" | while read line ;do {};done 众所周知管道会开启子shell,子shell内的数组,变量,函数在函数外部均不生效 #!/bin/bash echo "abc xyz" | while read line do new_var=$line done echo new_var is null: $new_var? 三、until循环 until CONDITION; do 循环体 done 进入条件: CONDITION 为false 退出条件: CONDITION 为true 四、continue特殊用法 continue [N]:提前结束第N层的本轮循环,最内层为第一层 默认N为1,只退一层循环。比如复杂的代码套了好几层的话,continue 2可以直接提前结束两层的循环,直接进入下一轮判断,continue候面的代码不执行了 五、break用法 break [N]:提前结束第N层循环,最内层为第1层 注意:这个直接结束第N层所有循环了,而continue只是结束第N层的本轮循环 六、shift命令 shift [n] 很重要,脚本中经常用到。将参数列表左移n次 [[email?protected] ~]# cat shift.sh #!/bin/bash #判断脚本参数是否为0,不为0则执行循环 while [ $# -ne 0 ];do echo $1 #打印第一个参数 shift #所有参数左移,第一个参数被挤走,第二个参数变成第一个参数 done [[email?protected] ~]# ./shift.sh a b c d f a b c d f 七、select循环与菜单 select经常与case一起用;还有就是PS3作为提示符;还有就是要配合break或exit退出循环 [[email?protected] ~]# cat select.sh #!/bin/bash PS3="你想干啥:" select choice in eating wc sleep quit do case $choice in eating) echo "you can eat some food now." ;; wc) echo "you can go go to wc now." ;; sleep) echo "you can go to sleep now." ;; quit) exit 0 esac done 效果 [[email?protected] ~]# bash select.sh 1) eating 2) wc 3) sleep 4) quit 你想干啥:1 you can eat some food now. 你想干啥:2 you can go go to wc now. 你想干啥:3 you can go to sleep now. 你想干啥:4 八、函数 载入函数:
九、删除函数 可以使用unset删除 比如:一个简单的函数,执行没有问题 [[email?protected] ~]# cat function.sh #!/bin/bash hi(){ echo hi } hi [[email?protected] ~]# bash function.sh hi 中间加一行unset,就报错了,因为函数被删除了 [[email?protected] ~]# cat function.sh #!/bin/bash hi(){ echo hi } unset hi hi [[email?protected] ~]# bash function.sh function.sh: line 6: hi: command not found 还可以通过定义空函数实现,这是我在系统中的脚本中发现的 # ubuntu的/lib/lsb/init-functions # Pre&Post empty function declaration,to be overriden from /lib/lsb/init-functions.d/* log_daemon_msg_pre () { :; } log_daemon_msg_post () { :; } log_begin_msg_pre () { :; } log_begin_msg_post () { :; } log_end_msg_pre () { :; } log_end_msg_post () { :; } log_action_msg_pre () { :; } log_action_msg_post () { :; } log_action_begin_msg_pre () { :; } log_action_begin_msg_post () { :; } log_action_end_msg_pre () { :; } log_action_end_msg_post () { :; } 十、函数变量的生存时间 环境变量:当前shell和子shell有效 本地变量:只在当前shell进程中有效,包括脚本函数 局部变量:函数的生命周期,函数结束时变量销毁 局部变量的定义:local AGE=20 十一、函数的递归 联想到fork炸弹 :(){:|:&};: 脚本实现 cat bomb.sh #!/bin/bash ./$0|./$0& 十二、信号的捕捉trap 看另一篇文章 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |