shell脚本进阶一览(for,while,continue,break,select等等)
脚本进阶一一、for循环的第二种写法:众所周知,for有两种写法第一种:for i in k8s-node{1..3};do setenforce 0;done第二种写法:C语言风格直接写怎么用:#for后必须写两个括号,又称双小括号写法[root@linux1 ~]# cat for_2.sh#!/bin/bashfor ((i=1,sum=0;i<=100;i+...
脚本进阶一
一、for循环的第二种写法:
众所周知,for有两种写法
- 第一种:for i in k8s-node{1..3};do setenforce 0;done
- 第二种写法:C语言风格
直接写怎么用:
#for后必须写两个括号,又称双小括号写法
[root@linux1 ~]# cat for_2.sh
#!/bin/bash
for ((i=1,sum=0;i<=100;i++));do
let sum+=i
done
echo "sum=${sum}"
[root@linux1 ~]# bash for_2.sh
sum=5050
二、while循环
我喜欢这样写,一直循环然后用break退出
[root@linux1 ~]# 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}"
[root@linux1 ~]# bash while_sum.sh
sum=5050
while的高级用法:读取标准输入的内容实现循环
[root@linux1 ~]# cat while_2.sh
#!/bin/bash
while read line
do
echo $line
done < /etc/fstab
[root@linux1 ~]# 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次
[root@linux1 ~]# cat shift.sh
#!/bin/bash
#判断脚本参数是否为0,不为0则执行循环
while [ $# -ne 0 ];do
echo $1 #打印第一个参数
shift #所有参数左移,第一个参数被挤走,第二个参数变成第一个参数
done
[root@linux1 ~]# ./shift.sh a b c d f
a
b
c
d
f
七、select循环与菜单
select经常与case一起用;还有就是PS3作为提示符;还有就是要配合break或exit退出循环
[root@linux1 ~]# 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
效果
[root@linux1 ~]# 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
八、函数
载入函数:
- . filename
- source filename
九、删除函数
可以使用unset删除
比如:一个简单的函数,执行没有问题
[root@linux1 ~]# cat function.sh
#!/bin/bash
hi(){
echo hi
}
hi
[root@linux1 ~]# bash function.sh
hi
中间加一行unset,就报错了,因为函数被删除了
[root@linux1 ~]# cat function.sh
#!/bin/bash
hi(){
echo hi
}
unset hi
hi
[root@linux1 ~]# 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
看另一篇文章
十四、数组
声明数组(两者不可相互转换):
- declare -a ARRAY_NAME 索引数组
- declare -A ARRAY_NAME 关联数组
数组元素赋值:
- ARRAY_NAME=("VAL1" "VAL2" "VAL3" ...)
- read -a ARRAY 交互式赋值
显示所有普通数组
declare -a
引用数组
-
引用数组元素
${ARRAY_NAME[INDEX]} 注意:省略[INDEX]表示引用下标为0的元素
- 引用数组所有元素
- 获取数组的长度
- 删除数组中某个元素。
- 删除整个数组
关联数组必须先声明后调用
数组这一块看另一篇文章吧
https://blog.51cto.com/14012942/2432919
十三、字符串处理
看另一篇文章吧
https://blog.51cto.com/14012942/2432954
十四、eval命令
eval命令将会首先扫描命令行进行所有的置换,然后再执行该命令。该命令 适用于那些一次扫描无法实现其功能的变量.该命令对变量进行两次扫描
[root@linux1 ~]# CMD=whoami
[root@linux1 ~]# echo $CMD
whoami
[root@linux1 ~]# eval $CMD
root
[root@linux1 ~]# n=10
[root@linux1 ~]# echo {1..$n}
{1..10}
[root@linux1 ~]# eval echo {1..$n}
1 2 3 4 5 6 7 8 9 10
十五、创建临时文件或目录
[root@linux1 tmp]# mktemp XXXXX
saXhh
[root@linux1 tmp]# mktemp XXXXX
SALVc
[root@linux1 tmp]# mktemp -d XXXXX
ltweX
[root@linux1 tmp]# mktemp -d XXXXX
OUXqe
[root@linux1 tmp]# ll
total 0
drwx------. 2 root root 6 Aug 27 15:09 ltweX
drwx------. 2 root root 6 Aug 27 15:09 OUXqe
-rw-------. 1 root root 0 Aug 27 15:09 SALVc
-rw-------. 1 root root 0 Aug 27 15:09 saXhh
[root@linux1 tmp]# mktemp -d `date +%T_%F`_XXXXX
15:10:40_2019-08-27_2QIKq
十六、install命令
该命令很强大,相当于多个命令的组合:cp,chmod,chown,mkdir等
可以自行看帮助,make install用的就是这个install
更多推荐
所有评论(0)