循环:
循环是一种重复执行一段代码的结构,只要满足循环的条件,会一直执行这个代码
结构
循环条件:在一定范围之内,按照指定的次数来执行循环
循环体:在指定的次数内执行的命令序列,只要条件满足,循环体会被一直执行.
循环和遍历
循环是操作,遍历是输出
遍历指的是对数据结构中每个元素进行一次访问的过程.通常和循环一起使用.访问的目的就是为了执行特定的操作.
循环的作用
1.重复执行代码,尤其是统一的,相同的,批量的操作.
2.可以提高代码的重复利用率
3.可以提高人工的效率,减少人工的干预,提高效率
4.简化程序的逻辑,减低代码的出错的可能性
常见循环
for循环 用于已知循环次数的场景
while循环 和for循环通用,常用与死循环
until循环 条件不满足才执行循环.
for循环的格式1
for 变量名称(前面没有$) in 范围
do
命令序列
done
示例
for i in {1..10}
do
echo $i
done
for循环格式2,类c语言的格式
for (( 表达式1;表达式2;表达式3 )) ; do
命令序列
done
表达式1:定义变量并且赋予初始值
表达式2:循环的方式
表达式3:循环的方式,变量每一次自增1
示例
for (( i=0;i<=5;i++ )) ; do
echo $i
done
for循环格式3,死循环
示例
for (( ; ; )) ; do
命令序列
done
双for循环语句
echo -n 不换行输出
echo -e 输出转义字符
\b 相当于退格键
\n 换行,相当于回车键
\f 也是换行,但是换行后的新行是连着上行的行尾
\t 相当于tab键,横向制表符
示例
for i in {1..9} ; do
for j in {1..9} ; do
echo -n $j
done
echo
done
while和until的语法使用
while 满足条件就执行循环,不满足条件才会退出.
使用场景:死循环或者不知道循环多少次,需要主动结束循环或者达到条件才结束循环
while [判断条件]
do
命令序列
done
示例
i=0
sumji=0
sumou=0
while [ $i -lt 100 ]
do
let i++
if [[ $(($i % 2 )) -eq 0 ]]
then
sumou=$(( $i+$sumou ))
else
sumji=$(( $i+$sumji ))
fi
done
echo "奇数和是 $sumji 偶数和是$sumou"
死循环
while [ true ] 永远为真,死循环
do
命令语句
done
until循环
条件不满足才执行循环,一旦条件成立,循环终止
until [条件判断]
do
命令序列
done
示例
until [ 1 -eq 2 ]
do
echo "循环了"
done
循环控制语句 continue和break
break 在循环内部,执行到break命令时,会立即跳出当前循环,并且终止,默认值是1
break 2 终止两层循环
continue 当执行到continue是,也是跳出当前循环,但是如果循环条件依然满足,会执行后续的循环条件,默认值是1
continue 2
exit 满足条件,立刻结束全部循环,不分内外多少层
示例1
for i in {1..10} ;do
if [ $i-eq 3];then
break
fi
echo $i
done
示例2
break2
内层循环到3中止,外层循环跟着中止
for i in {1..3}
do
echo $i
for j in {1..5}
do
if [ $j -eq 3 ]
then
break 2
fi
echo $j
done
done
示例3
continue2
内层循环到3跳出内层循环,外层循环还符合条件,继续执行
set -x #开启调试模式
for i in {1..3}
do
echo $i
for j in {1..5}
do
if [ $j -eq 3 ]
then
continue 2
fi
echo $j
done
done
sex +x #关闭调试模式
示例4
for i in {1..3}
do
echo $i
for j in {1..5}
do
if [ $j -eq 3 ]
then
exit 2
fi
echo $j
done
done
练习1
创建一个文件passwd.txt
在这个文件中创建三行,xy101,xy102,xy103
使用这个循环创建这个三个用户,统一设定密码为123456
for i in $( cat /root/passwd.txt )
do
useradd $i
echo 123456 | passwd --stdin $i
done
练习2
如何实现累加求和,1-100,一直相加,最后的结果是多少呢
sumou=0
sumji=0
for (( i=1 ; i<=100 ; i++ ))
do
if [[ $(( $i%2 )) -eq 0 ]]
then
sumou=$(( $sumou+$i ))
else
sumji=$(( $sumji+$i ))
fi
done
echo $sumou $sumji
练习3
自定义输入一个数,然后求从1到该数字的累加和,不要超过100
sum=0
read -p "输入一个0-100之间的随机数" num
for ((i=1 ; i<=$num ; i++ ))
do
sum=$(( $sum+$i ))
done
echo $sum
练习4
猜数字,输入一个0-100的随机数,这个随机数由系统生成
死循环,一直到用户猜中为止,猜中循环才会终止
猜大了,提示用户猜大了,猜笑了,提示用户猜小了,猜对了才终止,并提示用户你猜对了
猜了几次猜对了
a=$(( RANDOM%10+1 ))
echo "正确数字是 " $a
time=0
for (( ; ; ))
do
read -p "输入一个数字" num
let time++
if [[ $num -eq $a ]]
then
echo "恭喜你猜中了"
break
elif [[ $num -gt $a ]]
then
echo "你猜错了,数字偏大"
elif [[ $num -lt $a ]]
then
echo "你猜错了,数字偏小"
fi
done
echo "一共猜了 $time 次 "
练习5
逛淘宝选购商品,
每家商店有五种商品选购(衣服500元,裤子400元,鞋子350元,帽子150元,袜子50元),
每次选购完或不买都会提示用户是否继续逛下一家商店,
如果不再继续逛的话进行购物车结算总额。
#非最优写法
clothes=500
trousers=400
shoes=350
hat=150
stockings=500000
storenum=1
spend=0
for ((;;));do
echo "这里是第 $storenum 号商店 "
echo "店内商品有衣服$clothes 裤子$trousers 鞋子$shoes 帽子$hat 袜子$stockings "
echo "需要购买吗? y/n"
read -p " " choose1
if [[ $choose1 == "n" ]];then
echo "那你还需要去其他店里看看吗? y/n"
read -p " " choose2
if [[ $choose2 == "n" ]];then
if [[ $spend -eq 0 ]];then
echo "好的,慢走"
break
elif [[ $spend -gt 0 ]];then
echo "您这边消费了$spend元"
break
fi
elif [[ $choose2 == "y" ]];then
echo "好的,这边请"
storenum=$(( $storenum+1 ))
fi
elif [[ $choose1 == "y" ]];then
for ((;;)); do
echo "衣服$clothes 裤子$trousers 鞋子$shoes 帽子$hat 袜子$stockings"
echo "1:衣服 2:裤子 3:鞋子 4:帽子 5:袜子"
read -p " " choose3
case $choose3 in
1)
echo "已购买衣服"
spend=$(( $spend+$clothes ))
echo "继续吗? y/n"
read -p " " choose4
if [[ $choose4 == "n" ]]; then
break
fi
;;
2)
echo "已购买裤子"
spend=$(( $spend+$trousers ))
echo "继续吗? y/n"
read -p " " choose4
if [[ $choose4 == "n" ]]; then
break
fi
;;
3)
echo "已购买鞋子"
spend=$(( $spend+$shoes ))
echo "继续吗? y/n"
read -p " " choose4
if [[ $choose4 == "n" ]]
then
break
fi
;;
4)
echo "已购买帽子"
spend=$(( $spend+$hat ))
echo "继续吗? y/n"
read -p " " choose4
if [[ $choose4 == "n" ]]
then
break
fi
;;
5)
echo "已购买袜子"
spend=$(( $spend+$stockings ))
echo "继续吗? y/n"
read -p " " choose4
if [[ $choose4 == "n" ]]
then
break
fi
;;
esac
done
fi
done
练习6
某山顶上有一颗香蕉树,一只猴子第一天从树上摘了若干根香蕉,当即就吃了一半,还不过瘾,
又多吃了一根。第二天猴子又将剩下的香蕉吃了一半,禁不住诱惑,又多吃了一根香蕉。
依此类推,每天都将剩余的香蕉吃一半后再多吃一根。到了第十天,猴子发现只剩一根香蕉了,
请问这只猴子在第一天总共摘了多少根香蕉?
#第十天=1根
#第九天=(1+1)*2=4根
#第八天=(4+1)*2=10根
#第九天=(10+1)*2=22根
banana=1
echo "第10天有 $banana 根香蕉 "
for (( i=9;i>0;i-- ))
do
banana=$(( (banana+1) *2 ))
echo "第 $i 天有 $banana 根香蕉"
done
九九乘法表
for (( i = 1; i<=9; i++)) ; do
for (( j =1; j<=i; j++)) ; do
echo -ne "$j" "*" "$i" "=" $(( $i*$j )) "\t"
done
echo
done
练习7
倒直角三角形
for (( i=5; i>=1; i--)) ; do
for (( g=1; g<=i; g++)) ; do
echo -ne "*"
done
echo
done
倒等腰三角形
for (( i=5; i>=1; i--)) ; do
for (( j=1; j<=(5-i); j++)) ; do
echo -ne "#"
done
for (( g=1; g<=(2*i-1); g++)) ; do
echo -ne "*"
done
echo
done
练习8
打印出/opt下所有的文件,包括目录
练习9
利用for循环,将/opt目录下,所有以.txt结尾的文件合成一个文件,合并到xy102.txt文件
for file in /opt/*.txt
do
cat $file >> xy102.txt
done
练习10
测试一个网段,c类的ip地址,32位的网段,测试可以ping通的保留到/opt/hosts.txt里,如果不同,提示不通即可.
result=0
for ((i =1 ; i <=254; i++)) do
{
cip=192.168.118.$i
ping -c 2 $cip &> /dev/null
result=$?
if [[ result -eq 0 ]]
then
echo $cip >> /root/hosts.txt
else
echo "$cip" "ping不通"
fi
}& #把整个循环体的代码看做一整个内容,相当于并行,放入后台执行
done
练习11
计算器,实现整数的+,-,*,/,以及求%
jieguo=0
read -p "请输入第一个数" num1
for ((;;))
do
read -p "运算符是?" fu
read -p "请输入第二个数" num2
if [[ $fu == "+" ]]
then
jieguo=$(( $num1+$num2 ))
num1=jieguo
echo "结果是: " $jieguo
elif [[ $fu == "-" ]]
then
jieguo=$(( $num1-$num2 ))
num1=jieguo
echo "结果是: " $jieguo
elif [[ $fu == "*" ]]
then
jieguo=$(( $num1*$num2 ))
num1=jieguo
echo "结果是: " $jieguo
elif [[ $fu == "/" ]]
then
jieguo=$(( $num1/$num2 ))
num1=jieguo
echo "结果是: " $jieguo
elif [[ $fu == "%" ]]
then
jieguo=$(( $num1%$num2 ))
num1=jieguo
echo "结果是: " $jieguo
fi
done
练习12
定义好了一个密码,脚本判断密码输入是否正确,正确的密码是123456,输入正确提示正确,输入3次错误提示密码已被锁定
练习13
用户名存放在users.txt文件中,每行一个,判断文件里的用户名是否存在
如果存在,提示用户已存在
如果存在,但没有设置密码,要提示用户设置密码
如果用户不存在,创建用户,然后给用户创建密码
cat /etc/passwd | awdk -F: `{print $1}` | grep "$user"
cat /etc/shadow | grep "$user" | awd -F: `{print $2}`
touch users.txt
vim users.txt
zhangsan
lisi
wangwu
:wq
for i in $( cat /root/users.txt )
do
result=`cat /etc/passwd | awk -F: '{print $1}' | grep "$i"`
if [[ $result == "$i" ]]
then
echo "$i" "已查找到"
result=`cat /etc/shadow | grep "$i" | awk -F: '{print $2}'`
if [[ $result == "!!" ]]
then
echo "$i " "未设置密码,现在设置密码 "
passwd $i
else
echo "$i " "密码已设置"
fi
else
echo "$i" "未查找到,现在创建新用户和密码"
useradd $i
passwd $i
fi
done
练习14
使用循环语句 ,将一个0-255的十进制数转换成8位的二进制数
read -p "请输入一个0-255之间的整数:" num
for ((i=0;i<8;i++));do
quyu=$(($num%2))
num=$(($num/2))
echo $quyu
done