shell脚本进阶一(for,while,continue,break,select等等)

脚本进阶一

一、for循环的第二种写法:

众所周知,for有两种写法

  • 第一种:for i in k8s-node{1..3};do setenforce 0;done
  • 第二种写法:C语言风格

直接写怎么用:

#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

八、函数

载入函数:

  • . filename
  • source filename

九、删除函数

可以使用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

看另一篇文章

原文地址:https://blog.51cto.com/14012942/2432892

时间: 2024-10-30 21:19:51

shell脚本进阶一(for,while,continue,break,select等等)的相关文章

shell脚本进阶篇(上)

shell脚本是我们学习运维的难点,本篇内容简单举例shell脚本的进阶上篇,有任何技术上的指导,知识上的不足都欢迎指出点明. 流程控制 过程式编程语言: 顺序执行   选择执行  循环执行 条件选择if语句 ? 单分支 if 判断条件;then 条件为真的分支代码 fi 双分支 if 判断条件; then 条件为真的分支代码 else 条件为假的分支代码 fi 多分支 if 判断条件1; then 条件为真的分支代码 elif 判断条件2; then 条件为真的分支代码 elif 判断条件3;

shell脚本进阶

一.流程控制 流程控制语句,即用来实现对程序流程的选择.循环和返回等进行控制的语句. 1.条件判断 (1)if条件判断 普通if条件判断 格式: 嵌套if条件判断 格式: (2)case判断 简洁版多分支if语句,当if语句有多个elif时可以使用case语句代替,语言更简洁容易理解.使用场景:判断某个变量值是否为多种情形中的一种时使用. 格式: 示例: 执行结果: 2.循环 循环执行就是将循环体内的代码重复运行多次:运行的次数由进入循环的条件和退出循环决定. (1)for循环 格式: 列表:变

shell脚本进阶之循环判断

p.MsoNormal,li.MsoNormal,div.MsoNormal { margin: 0cm; margin-bottom: .0001pt; text-align: justify; font-size: 14.0pt; font-family: 等线 } h1 { margin-top: 15.6pt; margin-right: 0cm; margin-left: 0cm; margin-bottom: .0001pt; text-align: justify; line-he

shell脚本进阶(二)

select 循环与菜单 select variable in list do 循环体命令 done select 循环主要用于创建菜单,按数字顺序排列的菜单项将显示在标准错误上,并显示PS3 提示符,等待用户输入 用户输入菜单列表中的某个数字,执行相应的命令 用户输入被保存在内置变量REPLY 中. select 是个无限循环,因此要记住用break 命令退出循环,或用exit 命令终止脚本.也可以按ctrl+c 退出循环. select 经常和case 联合使用 与for 循环类似,可以省略

shell脚本进阶(一)

一.逻辑运算 变量: 本地变量.环境变量.局部变量.位置参数变量.特殊变量 变量赋值:name=value,export name=value,declare -x name=value 变量引用:$name,${name} 注意:有些时候{}不能省略,例如 echo "$valuemagedu.com" echo "${value}magedu.com" 撤销:unset name bash脚本编程,运行脚本 #!/bin/bash      #称为shebang

shell脚本进阶练习题---理解和练习

1.编写脚本/root/bin/createuser.sh, 实现如下功能:使用一个用户名做为参数,如果指定参数的用户存在,就显示其存在,否则添加之:显示添加的用户的id号等信息 2.判断/var/目录下所有文件的类型 3.添加10个用户user1-user10,密码为8位随机字符 4.编写脚本,提示请输入网络地址,如192.168.0.0,判断输入的网段中主机在线状态 有几个有意思点的shell脚本 5.九九乘法表 6.等腰三角形 7.国际象棋棋盘 不忘初心 砥砺前行!!! 原文地址:http

shell脚本进阶之信号的捕捉

shell脚本之信号的捕捉 ? trap,翻译过来就是陷阱的意思,shell脚本中的陷阱是专门用来捕捉信号的.啥信号呢?比如经常使用的kill -9,kill -15,CTRL+C等都属于信号 1.查看所有可用的信号 trap -l或kill -l即可 [[email protected] ~]# kill -l 63) SIGRTMAX-1 64) SIGRTMAX [[email protected] ~]# trap -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4)

shell脚本进阶之数组基础

SHELL脚本--shell数组基础 ? 数组和变量的区别:变量在内存中占用的空间是离散的,数组在内粗中开辟一段连续的大内存空间,随后数组中的每个元素都放入数组内存中.数组元素使用index标识. ? bash里有两种数组普通数组和关联数组.普通数组只能使用整数类形数值作为数组索引,关联数组可以使用字符串作为索引.关联数组的另外三种称呼:字典(dict),hash结构和映射(map),是一种key和value一一对应的关系. 一.普通数组 1.1定义普通数组 方法一: [[email prote

SHELL脚本进阶练习题

用for实现脚本 判断/var/目录下所有文件的类型 read -p "pleasr input directory: " DIS for F in ls $DIS;do   TY=file $DIS/$F | egrep -o "link|text|block|directory"   case $TY in   text)     echo "file $DIS/$F is file"     ;;   link)     echo &quo