大家好呀!今天简单聊一聊Shell的流程控制。任何一门编程语言的学习,在了解了其基本的语法规则和变量外,都是从基础的流程控制语句开始学习。流程控制无非是顺序、分支(选择)加上循环,对于任何一门编程语言而言都是类似的。
一、选择语句
1、语法结构
1)if语句
只有条件为真才会执行command命令
if [ condition ];then
command
command
fi
[ 条件 ] && command
2)if-else语句
只有条件为真才会执行command1,否则执行command2
if [ condition ];then
command1
else
command2
fi
或使用条件判断(逻辑与、逻辑或)
代码语言:javascript复制[ 条件 ] && command1 || command2
&&:前面的表达式为真,才会执行后面的内容
||:前面的表达式为假,才会执行后面的内容
3)if-elif-else语句
如果条件1满足,执行命令1后结束;如果条件1不满足,再看条件2,如果条件2满足执行命令2后结束;如果条件1和条件2都不满足执行命令3结束。
if [ condition1 ];then
command1
elif [ condition2 ];then
command2
else
command3
fi
4)嵌套if
代码语言:javascript复制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脚本
代码语言:javascript复制vim ping.sh
2)根据要求编写脚本
代码语言:javascript复制#!/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)
代码语言:javascript复制ping -c1 $1 &>/dev/null
[ $? -eq 0 ] && echo "当前主机和远程主机$1是互通的。" || echo "当前主机和远程主机$1是不通的。"
在执行脚本时可以让用户传入多个参数($#)
代码语言:javascript复制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)语法结构
代码语言:javascript复制for variable in {list}
do
command
command
…
done
或
代码语言:javascript复制for variable in a b c
do
command
command
done
2)eg:
输出1-5
代码语言:javascript复制#方式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的奇数
代码语言:javascript复制for i in {1..10..2};do echo $i;done
# 1 3 5 7 9
输出1-10的偶数(逆序)
代码语言:javascript复制# 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)语法结构
代码语言:javascript复制for variable
do
command
command
…
done
2)eg:
编写一个shell脚本,实现不带列表循环。
代码语言:javascript复制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)语法结构
代码语言:javascript复制for(( expr1;expr2;expr3 ))
do
command
command
…
done
expr1:定义变量并赋初值,expr2:循环的终止条件,expr3:循环变量的改变方式
2)案例
eg1
代码语言:javascript复制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脚本
代码语言:javascript复制vim test1.sh
2)根据要求编写脚本
代码语言:javascript复制#!/bin/bash
sum=0
for i in {1..100..2}
do
sum=$[ $i $sum ]
done
#打印1-100的奇数和
echo "1-100的奇数和为:$sum"
或
代码语言:javascript复制#!/bin/bash
sum=0
for (( i=1;i<=100;i =2))
do
let sum=sum $i
done
echo "1-100的奇数和为:$sum"
或
代码语言:javascript复制#!/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"
或
代码语言:javascript复制#!/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
代码语言:javascript复制#!/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整除的年份即为闰年。)
代码语言:javascript复制#!/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 语法结构
代码语言:javascript复制while 表达式
do
command...
done
3.2 案例
eg:打印1-5数字
1)for循环:
代码语言:javascript复制for ((i=1;i<=5;i ))
do
echo $i
done
2)while循环:
代码语言:javascript复制i=1
while [ $i -le 5 ]
do
echo $i
let i
done
4、until循环
4.1 语法结构
条件为假进入循环;条件为真退出循环
,与while循环相反。
until 条件表达式
do
command
command
...
done
eg:打印1-5
1)while循环:
代码语言:javascript复制i=1
while [ $i -le 5 ]
do
echo $i
let i
done
2)until循环:
代码语言:javascript复制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
代码语言:javascript复制#!/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
好了,以上就是今天这篇文章的全部内容了。如果你想及时看到我的文章,只需做这几个动作:点星标、点在看(包括赞)、评论、分享,我就会经常出现在您的常读列表,后面更新都会提醒。感谢大家的关注和支持,祝大家生活美满,学业有成,事业蒸蒸日上!