一文简述shell流程控制

2024-08-18 16:38:27 浏览数 (2)

大家好呀!今天简单聊一聊Shell的流程控制。任何一门编程语言的学习,在了解了其基本的语法规则和变量外,都是从基础的流程控制语句开始学习。流程控制无非是顺序、分支(选择)加上循环,对于任何一门编程语言而言都是类似的。

一、选择语句

1、语法结构

1)if语句

只有条件为真才会执行command命令

代码语言:powershell复制
if [ condition ];then
		command
		command
fi

[ 条件 ] && command

2)if-else语句

只有条件为真才会执行command1,否则执行command2

代码语言:powershell复制
if [ condition ];then
		command1
	else
		command2
fi

或使用条件判断(逻辑与、逻辑或)

代码语言:powershell复制
[ 条件 ] && command1 || command2

&&:前面的表达式为真,才会执行后面的内容

||:前面的表达式为假,才会执行后面的内容

3)if-elif-else语句

如果条件1满足,执行命令1后结束;如果条件1不满足,再看条件2,如果条件2满足执行命令2后结束;如果条件1和条件2都不满足执行命令3结束。

代码语言:powershell复制
if [ condition1 ];then
		command1  
	elif [ condition2 ];then
		command2 
	else
		command3
fi

4)嵌套if

代码语言:powershell复制
if [ condition1 ];then
		command1		
		if [ condition2 ];then
			command2
		fi
	else
		if [ condition3 ];then
			command3
		elif [ condition4 ];then
			command4
		else
			command5
		fi
fi

2、案例

判断当前主机和远程主机是否ping通

1)创建ping.sh脚本

代码语言:powershell复制
vim ping.sh

2)根据要求编写脚本

代码语言:powershell复制
#!/bin/bash

# Name: ping.sh
# Path: /shell02/ping.sh
# Usage: /shell02/ping.sh
# Update: 2024-08-08 21:56
# ...

#获取远程主机的IP地址(定义变量让用户自己输入)
read -p "请输入你要ping的远程主机IP:" IP
#使用ping命令来判断是否和远程主机互通
ping -c1 $IP &>/dev/null
if [ $? -eq 0 ];then
	echo "当前主机和远程主机$IP是互通的。"	
else
	echo "当前主机和远程主机$IP是不通的。"
fi

-c:次数,ping -c1表示ping 1次

注:/dev/null 属于字符特殊文件,它属于空设备,是一个特殊的设备文件,它会丢弃一切写入其中的数据,写入它的内容都会永远丢失。此处将ping的结果重定向到空设备文件,即不显示ping结果的具体信息

优化:在执行脚本时直接让用户传入一个参数($1)

代码语言:powershell复制
ping -c1 $1 &>/dev/null
[ $? -eq 0 ] && echo "当前主机和远程主机$1是互通的。" || echo "当前主机和远程主机$1是不通的。"

在执行脚本时可以让用户传入多个参数($#)

代码语言:powershell复制
if [ $# -ne 1 ];then
        echo "Usage:$0 remote_ip" && exit
fi
# 将上述if语句写成1行条件判断
[ $# -ne 1 ] && echo "Usage:$0 remote_ip" && exit

ping -c1 $1 &>/dev/null
[ $? -eq 0 ] && echo "当前主机和远程主机$1是互通的。" || echo "当前主机和远程主机$1是不通的。"

exit:退出,直接退出程序

$0:脚本本身的名字

$#:脚本后面接的参数的个数

$1~$9:位置参数变量

二、循环语句

1、for循环

1.1 列表循环

列表for循环:用于将一组命令执行已知的次数

注:循环次数由列表决定。

1)语法结构

代码语言:powershell复制
for variable in {list}
     do
          command 
          command
          …
     done

代码语言:powershell复制
for variable in a b c
     do
         command
         command
     done

2)eg:

输出1-5

代码语言:powershell复制
#方式1
for i in {1..5};do echo $i;done
#方式2
for i in `seq 5`;do echo $i;done
#方式3
for i in $(seq 5);do echo $i;done
#方式4
for i in 1 2 3 4 5;do echo $i;done

输出1-10的奇数

代码语言:powershell复制
for i in {1..10..2};do echo $i;done
# 1 3 5 7 9

输出1-10的偶数(逆序)

代码语言:powershell复制
# 10 8 6 4 2
for i in {10..1..-2};do echo $i;done
# 或
for i in {10..1..2};do echo $i;done

用反引号,将shell命令引起来,可以将命令的输出值赋给变量。

反撇号:反撇号和$()一样,引号或括号里的命令会优先执行,如果存在嵌套,使用$(),反撇号不能用

1.2 不带列表循环

循环次数由用户或脚本后面参数个数决定

1)语法结构

代码语言:powershell复制
for variable
    do
        command 
        command
        …
   done

2)eg:

编写一个shell脚本,实现不带列表循环。

代码语言:powershell复制
vim test.sh

#!/bin/bash
for i
do
	echo $var
done

echo "脚本后面有$#个参数"

1)do...done为循环体,do开始循环,done结束循环

2)非列表循环,变量取值由用户决定。脚本后面传一个参数1,就会把1传给参数i,就会打印出来1

3)使用bash -x查看脚本的执行过程。

1.3 类C风格

1)语法结构

代码语言:powershell复制
for(( expr1;expr2;expr3 ))
	do
		command
		command
		…
	done

expr1:定义变量并赋初值

expr2:循环的终止条件

expr3:循环变量的改变方式

2)案例

eg1

代码语言:powershell复制
for (( i=1;i<=5;i  ))
	do
		echo $i
	done

for ((i=1;i<=10;i =2));do echo $i;done
for ((i=2;i<=10;i =2));do echo $i;done

注:类C风格循环次数由循环终止条件和循环变量变化方式决定。

eg2:计算1到100的奇数和

1)创建test1.sh脚本

代码语言:powershell复制
vim test1.sh

2)根据要求编写脚本

代码语言:powershell复制
#!/bin/bash
sum=0
for i in {1..100..2}
do
	sum=$[ $i   $sum ]
done
#打印1-100的奇数和
echo "1-100的奇数和为:$sum"

代码语言:powershell复制
#!/bin/bash
sum=0
for (( i=1;i<=100;i =2))
do
	let sum=sum $i
done
echo "1-100的奇数和为:$sum"

代码语言:powershell复制
#!/bin/bash
sum=0
for ((i=1;i<=100;i  ))
do
	if [ $[$i%2] -ne 0 ];then
	let sum=sum $i
	fi
done
echo "1-100的奇数和是:$sum"

代码语言:powershell复制
#!/bin/bash
sum=0
for ((i=1;i<=100;i  ))
do
	[ $[$i%2] -eq 0 ] && true  || let sum=sum $i
done
echo "1-100的奇数和是:$sum"

真 => true或:

假 => false

2、循环控制

循环体: do...done之间的内容

2.1 控制语句

1)continue:跳过所在的本次循环,继续下一次循环。

2)break:用于结束当前所在的整个循环。

3)exit:直接跳出程序

2.2 eg

eg1:输入一个正整数,判断是否为质数(素数)

质数:只能被1和它本身整除的数叫质数。

2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

代码语言:powershell复制
#!/bin/bash
read -p "请输入一个正整数字:" number

[ $number -eq 1 ] && echo "$number不是质数" && exit
[ $number -eq 2 ] && echo "$number是质数" && exit

for i in `seq 2 $[$number-1]`
	do
	 [ $[$number%$i] -eq 0 ] && echo "$number不是质数" && exit
	done
echo "$number是质数" && exit

bash -x for6.sh

eg2:输入一个年份,判断是否是润年(能被4整除但不能被100整除,或能被400整除的年份即为闰年。)

代码语言:powershell复制
#!/bin/bash
read -p "Please input year:(2017)" year
if [ $[$year%4] -eq 0 -a $[$year0] -ne 0 ];then
	echo "$year is leap year"
elif [ $[$year@0] -eq 0 ];then
	echo "$year is leap year"
else
	echo "$year is not leap year"
fi

3、while循环

条件为真进入循环;条件为假退出循环

3.1 语法结构
代码语言:powershell复制
while 表达式
	do
		command...
	done
3.2 案例

eg:打印1-5数字

1)for循环:

代码语言:powershell复制
for ((i=1;i<=5;i  ))
do
	echo $i
done

2)while循环:

代码语言:powershell复制
i=1
while [ $i -le 5 ]
do
	echo $i
	let i  
done

4、until循环

4.1 语法结构

条件为假进入循环;条件为真退出循环,与while循环相反。

代码语言:shell复制
until 条件表达式
	do
		command
		command
		...
	done

eg:打印1-5

1)while循环:

代码语言:shell复制
i=1
while [ $i -le 5 ]
do
	echo $i
	let i  
done

2)until循环:

代码语言:shell复制
i=1
until (( $i > 5 )) 
do
	echo $i
	let i  
done
4.2 案例

使用until语句批量创建10个用户,要求stu1-stu5用户的UID分别为1001-1005;stu6~stu10用户的家目录分别在/rhome/stu6-/rhome/stu10

代码语言:powershell复制
#!/bin/bash
i=1
until [ $i -gt 10 ]
do
	if [ $i -le 5 ];then
		useradd -u $[1000 $i] stu$i && echo 123|passwd --stdin stu$i
	else
		[ ! -d /rhome ] && mkdir /rhome
		useradd -d /rhome/stu$i stu$i && echo 123|passwd --stdin stu$i		
	fi
let i  
done

0 人点赞