Shell基础之流程循环控制语句

目录

for循环

带列表循环

不带列表循环

类C风格循环

while循环

语法

无限循环

使用示例

until循环

基本语法

示例

select循环

语法格式

嵌套循环

break和continue

break的使用

continue的使用


在shell 中循环有以下几种:

|------------------|
| for 循环 |
| while 循环 |
| until 循环 |
| select 循环 |
| break 和 continue |

for循环

在shell中,for循环有两种情况

|--------|
| 带列表循环 |
| 不带列表循环 |

带列表循环

语法:

复制代码
for 循环变量 in 列表
do
    执行语句
    ...
done

在语法中,循环变量是每次循环时得到的列表的某一数据,当循环一次结束后,再获取另一个数,然后再执行 do 里面的语句,依此类推,直到列表中数据循环完结

for 循环中的列表中的数据是以空格来进行分隔的

示例:

直到列出列表的所有元素

代码示例:

复制代码
[root@openEuler ~]# cat for1.sh
#!/bin/bash

for var in 192.168.72.130 192.168.72.131 192.168.72.132
do
	echo $var
done
[root@openEuler ~]# bash for1.sh
192.168.72.130
192.168.72.131
192.168.72.132

还可以修改如下:

复制代码
[root@openEuler ~]# cat for1.sh 
#!/bin/bash

for var in 192.168.72.13{0..3}
do
	echo $var
done
[root@openEuler ~]# bash for1.sh
192.168.72.130
192.168.72.131
192.168.72.132
192.168.72.133

还可以使用 seq 命令来生成列表数据:

复制代码
[root@openEuler ~]# cat for1.sh
#!/bin/bash

for var in $(seq -f "192.168.72.13%1g" 1 5)
do
	echo $var
done
[root@openEuler ~]# bash for1.sh 
192.168.72.131
192.168.72.132
192.168.72.133
192.168.72.134
192.168.72.135

在带列表的 for 循环中,还可以指定循环的步长

语法:

复制代码
for 循环变量 in {开始..结束..步长}
do
   语句
   ....
done

示例:

循环输入1~10中的奇数

复制代码
[root@openEuler ~]# cat for2.sh 
#!/bin/bash

for v in {1..10..2}
do
	echo $v
done
[root@openEuler ~]# bash for2.sh 
1
3
5
7
9

示例:

获取根目录下所有文件名作为变量的值打印输出

代码示例:

复制代码
[root@openEuler ~]# cat for3.sh 
#!/bin/bash

for file in $(ls -F / | grep -v /$)
do
	echo $file
done


[root@openEuler ~]# bash for3.sh 
bin@
lib@
lib64@
sbin@

示例:

打印出如下的语句中字符数不大于6的单词

hello world rabbit favorite eat apple cabbage

代码示例:

复制代码
[root@openEuler ~]# cat for4.sh 
#!/bin/bash

for word in hello world rabbit favorite eat apple cabbage
do
	if [ `expr length ${word}` -le 6 ]; then
		echo $word
	fi
done
[root@openEuler ~]# bash for4.sh 
hello
world
rabbit
eat
apple

不带列表循环

语法:

复制代码
for 循环变量
do
	语句
	...
done

示例:

循环输入所有的参数

代码示例:

复制代码
[root@openEuler ~]# cat for5.sh
#!/bin/bash

for v in $@
do
	echo $v
done
[root@openEuler ~]# bash for5.sh 
[root@openEuler ~]# bash for5.sh {1..5}
1
2
3
4
5

类C风格循环

语法:

复制代码
for ((表达式1;表达式2;表达式3))
do
	语句
done

示例:

批量创建用户,用户名以 test 开头,按数字序号变化,一共添加30个账号,名称如:test01、test02、test03、......、test10、......、test30,用户初始密码为:Abc123456

代码示例:

复制代码
[root@openEuler ~]# cat for6.sh
#!/bin/bash

for ((i=1;i<=30;i++))
do
	if [ $i -lt 10 ]; then
		user=test0$i
	else
		user=test$i
	fi
	if ! id -u $user &> /dev/null
	then
		useradd $user
		echo "Abc123456" | passwd --stdin $user &> /dev/null
	else
		echo "$user is exists"
	fi
done

[root@openEuler ~]# bash for6.sh
[root@openEuler ~]# grep test /etc/passwd
test01:x:1001:1001::/home/test01:/bin/bash
test02:x:1002:1002::/home/test02:/bin/bash
test03:x:1003:1003::/home/test03:/bin/bash
test04:x:1004:1004::/home/test04:/bin/bash

方式二:

复制代码
[root@openEuler ~]# cat for7.sh 
#!/bin/bash

for u in `seq -f "test%02g" 1 30`
do
	if ! id -u $u &>/dev/null
           useradd $u
	   echo "Haha123123" | passwd --stdin $u
	fi
done

while循环

语法

复制代码
while [ 条件表达式 ]
do
	语句
	语句
done

示例:

循环输出1~10这几个数

代码示例:

复制代码
[root@openEuler ~]# cat while1.sh 
#!/bin/bash

i=1
while [ $i -le 10 ]
do
	echo $i
	let i++
done

示例:

使用exec读取指定文件的内容并循环输出,文件内容如下:

复制代码
[root@openEuler ~]# cat myfile
open
openlab
openlab123
linux
readhat

代码示例:

复制代码
# 第一步创建文件及内容
[root@openEuler ~]# cat > myfile << EOF
> open
> openlab
> openlab123
> linux
> readhat
> EOF
[root@openEuler ~]# cat myfile 
open
openlab
openlab123
linux
readhat
# 第二步:编写脚本来实现文件读取并循环输出
[root@openEuler ~]# cat while2.sh 
#!/bin/bash

exec < myfile

while read line
do
	echo $line
done
[root@openEuler ~]# bash while2.sh 
open
openlab
openlab123
linux
readhat

方式二:

复制代码
[root@openEuler ~]# cat while3.sh 
#!/bin/bash

while read line
do
	echo $line
done < myfile
[root@openEuler ~]# bash while3.sh 
open
openlab
openlab123
linux
readhat

无限循环

在while的表达式中,可以指定以下几个特殊值:

|-------|--------------------|
| true | 会一直循环,而且它的状态返码是0 |
| false | 不做任何事情,表示成功,状态码为0 |
| : | 作用与true相同,都是进行无限循环 |

代码示例:

复制代码
[root@openEuler ~]# while true ; do echo 123123 ; done   #会一直循环

[root@openEuler ~]# while false ; do echo 123123 ; done
[root@openEuler ~]# echo $?
0

[root@openEuler ~]# while : ; do echo 123123 ; done

使用示例

猜商品的价格,通过变量RANDOM来获取随机的价格,然后提示用户猜价格,并记录次数,猜中退出,或次数达到5次也退出

代码示例:

复制代码
[root@openEuler ~]# cat while4.sh 
#!/bin/bash

price=$[ $RANDOM % 100 ]
time=0

while true
do
	read -p 'Please enter product price [0-99]: ' input
	let time++
	if [ $input -eq $price ]; then
		echo 'Good luck, you guessed it.'
		echo 'You have guessed $time times.'
		exit 0
	elif [ $input -gt $price ]; then
		echo "$input is to high"
	else
		echo "$input is to low"
	fi
	if [ $time -eq 5 ]; then
		echo "You have guessed is 5 times. exit"
		exit 1
	fi
done
[root@openEuler ~]# bash while4.sh 
Please enter product price [0-99]: 50
50 is to low
Please enter product price [0-99]: 80
80 is to high
Please enter product price [0-99]: 70
70 is to high
Please enter product price [0-99]: 60
60 is to low
Please enter product price [0-99]: 65
65 is to low
You have guessed is 5 times. exit
[root@openEuler ~]# 

示例:

使用while读取文件,文件的内容如下:

复制代码
192.168.72.131  22
192.168.72.132  23
192.168.72.133  22

要求:

输出的格式为:

复制代码
IP: 192.168.72.131, PORT: 22
IP: 192.168.72.132, PORT: 23
IP: 192.168.72.133, PORT: 22

代码示例:

复制代码
# 1. 创建文件
[root@openEuler ~]# cat ips
192.168.72.131  22
192.168.72.132  23
192.168.72.133  22

# 2. 编写脚本 
[root@openEuler ~]# cat while6.sh 
#!/bin/bash

while read line
do
	IP=`echo $line|cut -d" " -f1`   # 也可以使用awk来实现,如:IP=`echo $line|awk '{print $1}'`
	PORT=$(echo $line|cut -d " " -f 2)
	echo "IP:$IP, PORT:${PORT}"
done < ips

# 3. 运行测试
[root@openEuler ~]# bash while6.sh 
IP:192.168.72.131, PORT:22
IP:192.168.72.132, PORT:23
IP:192.168.72.133, PORT:22

until循环

until循环和while循环的作用是一样的,都重复执行某些代码,但是它和while循环也有区别:until循环是条件不满足时才循环,条件满足则退出;而while循环是条件满足都循环,而条件不满足则退出

基本语法

复制代码
until [ 条件表达式 ]
do
	要重复执行的语句
done

示例

循环输出0~10之间的数

代码示例:

复制代码
[root@openEuler ~]# cat until1.sh 
#!/bin/bash

i=0

#while [ $i -lt 10 ]
#do
#	echo $i
#	let i++
#done

until [ $i -ge 10 ]
do
	echo $i
	i=$((i+1))
done

[root@openEuler ~]# bash until1.sh 
0
1
2
3
4
5
6
7
8
9

select循环

select循环语句主要功能是创建选择菜单,在执行带有select循环语句脚本时,会输出按照数字列表

语法格式

复制代码
select 变量名 [ in 菜单值列表 ]
do
	语句
done

示例:

选择MySQL版本

代码示例:

复制代码
[root@openEuler ~]# cat select1.sh 
#!/bin/bash

select mysql_version in 5.6 5.7 8.0
do
	echo $mysql_version
done
[root@openEuler ~]# bash select1.sh 
1) 5.6
2) 5.7
3) 8.0
#? 2
5.7
#? 3
8.0
#? ^C

示例:

选择水果,假如有以下水果可以选择:

Apple、Banana、Pear、Watermelons、Grape

代码示例:

复制代码
[root@openEuler ~]# cat select2.sh 
#!/bin/bash

echo "Choose your favorite fruit: "
select fruit in Apple Banana Pear Watermelons Grape
do
	echo
	echo "Your favorite fruit is $fruit."
	#break
done

[root@openEuler ~]# bash select2.sh 
Choose your favorite fruit: 
1) Apple
2) Banana
3) Pear
4) Watermelons
5) Grape
#? 1

Your favorite fruit is Apple.
#? 2

Your favorite fruit is Banana.
#? 4

Your favorite fruit is Watermelons.
#? ^C

代码完善:

在上面示例中,没有办法在选择水果后退出,它会一直让我们进行选择,如果希望选择后退出则需要添加break

复制代码
[root@openEuler ~]# cat select2.sh 
#!/bin/bash

echo "Choose your favorite fruit: "
select fruit in Apple Banana Pear Watermelons Grape
do
	echo
	echo "Your favorite fruit is $fruit."
	break
done

[root@openEuler ~]# bash select2.sh 
Choose your favorite fruit: 
1) Apple
2) Banana
3) Pear
4) Watermelons
5) Grape
#? 3

Your favorite fruit is Pear.
[root@openEuler ~]# 

嵌套循环

示例:

打印九九乘法表

复制代码
[root@openEuler ~]# cat ninetable.sh 
#!/bin/bash
for i in `seq 9`
do
	for j in `seq 9`
	do
		#[ $j -le $i ] && echo -n "$i*$j = `expr $i \* $j`  "
		[ $j -le $i ] && echo -n "$i*$j = `echo $((i*j))` "
	done
	echo " "
done


[root@openEuler ~]# bash ninetable.sh 
1*1 = 1  
2*1 = 2 2*2 = 4  
3*1 = 3 3*2 = 6 3*3 = 9  
4*1 = 4 4*2 = 8 4*3 = 12 4*4 = 16  
5*1 = 5 5*2 = 10 5*3 = 15 5*4 = 20 5*5 = 25  
6*1 = 6 6*2 = 12 6*3 = 18 6*4 = 24 6*5 = 30 6*6 = 36  
7*1 = 7 7*2 = 14 7*3 = 21 7*4 = 28 7*5 = 35 7*6 = 42 7*7 = 49  
8*1 = 8 8*2 = 16 8*3 = 24 8*4 = 32 8*5 = 40 8*6 = 48 8*7 = 56 8*8 = 64  
9*1 = 9 9*2 = 18 9*3 = 27 9*4 = 36 9*5 = 45 9*6 = 54 9*7 = 63 9*8 = 72 9*9 = 81

示例:

打印三角形(10行10列)

复制代码
[root@openEuler ~]# cat triangle.sh 
#!/bin/bash

for i in {1..9}
do
	for ((col=1;col<10-i;col++))
	do
		echo -n " "
	done
	for ((k=1; k<=i; k++))
	do
		echo -n "$i "
	done
	echo " "
done


[root@openEuler ~]# bash triangle.sh 
        1  
       2 2  
      3 3 3  
     4 4 4 4  
    5 5 5 5 5  
   6 6 6 6 6 6  
  7 7 7 7 7 7 7  
 8 8 8 8 8 8 8 8  
9 9 9 9 9 9 9 9 9 

break和continue

break是用于循环退出,而continue是结束本次循环,进入下一次循环

break的使用

示例:

复制代码
[root@openEuler ~]# cat break.sh 
#!/bin/bash

for i in `seq 9`
do
	if [ $i -eq 5 ] ; then
		break
	else
		echo $i
	fi
done
[root@openEuler ~]# bash break.sh 
1
2
3
4

continue的使用

示例:

复制代码
[root@openEuler ~]# cat continue.sh 
#!/bin/bash

for i in `seq 9`
do
	if [ $i -eq 5 ] ; then
		continue
	else
		echo $i
	fi
done
[root@openEuler ~]# bash continue.sh 
1
2
3
4
6
7
8
9
相关推荐
Sheep Shaun1 天前
如何让一个进程诞生、工作、终止并等待回收?——探索Linux进程控制与Shell的诞生
linux·服务器·数据结构·c++·算法·shell·进程控制
dingdingfish2 天前
Bash 学习 - 第1章:Introduction
bash·shell·programming·introduction
pr_note4 天前
legality检查
shell·tcl
啥都不懂的小小白5 天前
Shell脚本编程入门:从零基础到实战掌握
前端·shell
dingdingfish9 天前
GNU Parallel 学习 - 第1章:How to read this book
bash·shell·gnu·parallel
似霰12 天前
Linux Shell 脚本编程——核心基础语法
linux·shell
似霰12 天前
Linux Shell 脚本编程——脚本自动化基础
linux·自动化·shell
偷学技术的梁胖胖yo14 天前
Shell脚本中连接数据库查询数据报错 “No such file or directory“以及函数传参数组
linux·mysql·shell
纵有疾風起22 天前
【Linux 系统开发】基础开发工具详解:软件包管理器、编辑器。编译器开发实战
linux·服务器·开发语言·经验分享·bash·shell
gis分享者24 天前
Shell 脚本中如何使用 here document 实现多行文本输入? (中等)
shell·脚本·document·多行·文本输入·here