1. for循环
for 变量名 in 列表;do
循环体
done
执行机制:
- 依次将列表中的元素赋值给“变量名” ; 每次赋值后即执行一次循环体; 直到列表中的元素耗尽,循环结束
1.1. 列表生成方式:
列表生成方式有多重,详情可查看其他博客所总结。
- 直接给出列表
- 整数列表:
- (a)
{start..end} - (b)
$(seq [start [step]] end)
- (a)
- 返回列表的命令
$(COMMAND)
- 使用glob通配符,如:
*.sh - 变量引用
$@, $*
1.2. for特殊格式(详细看各种括号对比的部分)
- 双小括号方法,即
((…))格式,也可以用于算术运算- 双小括号方法也可以使bash Shell实现C语言风格的变量操作
- I=10
- ((I++))
- 双小括号方法也可以使bash Shell实现C语言风格的变量操作
- for循环的C语言模式:for ((控制变量初始化;条件判断表达式;控制变量的修正表达式)) do 循环体 done
- 控制变量初始化:仅在运行到循环代码段时执行一次
- 控制变量的修正表达式:每轮循环结束会先进行控制变量修正运算,而后再做条件判断
- 这种写法双小括号内的判断是按照C语言风格,而不是
-eq这类shell中test风格的
2. while循环
while CONDITION; do
循环体
done
CONDITION:循环控制条件;
- 进入循环之前,先做一次判断;每一次循环之后会再次做判断;条件为“true”,则执行一次循环;直到条件测试状态为“false”终止循环
- 因此:CONDTION一般应该有循环控制变量;而此变量的值会在循环体不断地被修正
进入条件:
- CONDITION为true
退出条件:
- CONDITION为false
3. until循环
until CONDITION; do
循环体
done
进入条件:
- CONDITION 为false
退出条件:
- CONDITION 为true
4. 循环控制语句
4.1. continue
用于循环体中
continue [N]:提前结束第N层的本轮循环,而直接进入下一轮判断;最内层为第1层举例:
while CONDTIITON1; do CMD1 ... if CONDITION2; then continue fi CMDn ... done
4.2. break
- 用于循环体中
break [N]:提前结束第N层循环,最内层为第1层- 举例:while CONDTIITON1; do CMD1 ... if CONDITION2; then break fi CMDn ... done
4.3. 注意点:
- continue只是结束此这一次循环(默认最内层),然后继续下一次循环。它仍然在此循环内,只是continue下面的语句在此次循环中不再执行了。如果后面加上数字,就是跳到数字所在的循环层数内继续执行数字所在层的后面所剩的循环次数(根据判断条件判断的),而比数字小的循环则不再执行(相当于break掉了比数字小的循环)
- break相当于此循环直接停止并跳出(默认最内层),后面加上数字就代表了它直接跳出数字所在层的循环(跳到数字所在层的更外一层,然后执行更外一层的命令,而continue是跳到数字所在层继续执行数字所在层的剩下的循环)。
- 注意break只是循环退出了,并是不exit脚本退出。
- 还有一点就是假如有2层或者多层循环,break 退出当前层循环之后它是继续执行外层循环中在当前循环后面的命令,而contine 2则跳到外层循环之后直接从外层循环的开头重新进行下一轮循环了。
4.4. shift命令
shift [n]- 用于将参量列表 list 左移指定次数,缺省为左移一次。
- 参量列表 list 一旦被移动,最左端的那个参数就从列表中删除。 while 循环遍历位置参量列表时,常用到 shift
- 例如:./doit.sh a b c d e f g h ./shfit.sh a b c d e f g h 示例:doit.sh #!/bin/bash # Name: doit.sh # Purpose: shift through command line arguments # Usage: doit.sh [args] while [ $# -gt 0 ] # or while (( $# > 0 )) do echo $* shift done 示例:shift.sh #!/bin/bash #step through all the positional parameters until [ -z "$1" ] do echo "$1" shift done echo
4.5. 创建无限循环
while true; do
循环体
done
until false; do
循环体
Done
4.6. 特殊用法(很实用)
遍历文件每一行这个写法很实用,参考自己写的创建用户的脚本读入每一行的命令就知道为何实用了(因为它只把换行符当做分隔符,而不把空格当做分隔符,每一行当做一个长字符串存入变量中)
4.6.1. while循环的特殊用法(遍历文件的每一行)
while read line; do
循环体
done < /PATH/FROM/SOMEFILE
- 依次读取/PATH/FROM/SOMEFILE文件中的每一行,且将行赋值给变量line
4.6.1.1. while read line 的IFS分隔符注意点
详情查看脚本练习测试常用章节中的第10项
4.6.2. select循环与菜单
PS3="Please input a number:"
select variable in list
do
循环体命令
done
- select 循环主要用于创建菜单,按数字顺序排列的菜单项将显示在标准错误上,并显示 PS3 提示符,等待用户输入
- 用户输入菜单列表中的某个数字,执行相应的命令
- 其具体逻辑就是当用户输入
list中元素相对应的数字的时候,会把select命令中的variable赋值为用户输入的数字对应的list中的相对应的元素; - 然后通过这个variable进行判断(利用case语句)从而执行相对应的功能。
- 其具体逻辑就是当用户输入
- 用户输入被保存在内置变量 REPLY 中(和read的一样)
- 这里一定要注意,用户输入的内容(可以是数字,也可以是任何其他的字符串等等)和select中的
variable并不是同一个变量; - 用户输入的内容不论是什么都会保存在REPLY中,只不过当用户输入内容编号和list中的元素相同的时候,此时
REPLY内容是用户输入的编号,而variable里面的内容是list中相对应编号的元素。
- 这里一定要注意,用户输入的内容(可以是数字,也可以是任何其他的字符串等等)和select中的
- select 是个无限循环,因此要记住用 break 命令退出循环,或用 exit 命令终止脚本。也可以按 ctrl+c 退出循环
- select 经常和 case 联合使用
4.6.3. select命令执行的时候,它的逻辑是这样的:
- 默认设置
REPLY和variable变量为空值 - prompt数字编号和list的元素相对应的一个列表出来
- 当用户什么都不输入直接按回车的话,返回第1步重新开始(此时也就会重新再prompt一遍)
- 只要用户输入任意字符再按回车(空格也算,除了什么都不输入直接按回车之外都可以),把用户输入的字符赋值到
REPLY变量中,继续下一步 - 如果输入的字符是数字编号同时对应到了list中的编号,则会把select中的
varible变量赋值为list中对应输入的编号的元素;如果用户输入的不是数字或者并没有对应到list中的编号,则什么都不做,保持variable变量为空,继续下一步 - 按顺序执行循环体中的内容
- 一般循环体会利用case语句和variable进行判断执行各种命令
- 同时会设置一个退出循环的break判断语句,从而能够退出循环
- 如果没有进行任何判断或者break语句,则会把循环体的内容从上到下执行一遍
- 如果没有退出(break)循环,则返回第一步重新循环执行
注意 :与 for 循环类似,可以省略 in list,此时使用位置参量
PS3="please input a number:"
select menu in backup clean config start stop status restart quit;do
case $menu in
*)
echo $REPLY
echo $menu;;
esac
done
测试 REPLY和 variabel(没有退出循环,也没用case语句):
#!/bin/bash
select name in test1 test2 test3 ;do
echo name=$name;
echo REPLY=$REPLY;
done;
~
留言