Shell编程之循环语句实例

Shell编程之循环语句实例

循环语句

for循环语句

  • 读取不同的变量值,用来逐个执行同一组命令

    for 变量名 in 取值列表   //连续范围取值可以{1..3} {1 2 3 } $(seq 1 3)
    					  //for ((i=1;i <=3; i++))
    					  //以行、空格、制表符来识别列表
    	//for i in {2..10..2},for i in `seq 2 2 10`每次自增2		  
    do(或"(")
    	命令序列
    done(或")"
    #!/bin/bash
    # 输出1到100的整数并判断奇偶
    
    for i in {1..100}
    do
    	j=$[ $i % 2 ] # 除二取余,奇数得到1,偶数得到0
    	if [ $j -eq 0 ];then
    		echo -ne "$i 为奇数\t"
    	else
    		echo "$i 为偶数"
    done
    
    #!/bin/bash
    # 按给定文件中的用户名逐个创建用户,并设置密码
    
    users=$(cat /etc/passwd | awk -F: '{print $1}') # 获取已存在的用户名
    
    for username in $(cat /opt/users.txt)  # 事先准备的一行一个用户名的txt文件
    do
    	echo $users | grep $name > /dev/null
    	if [ $? -eq 0 ]
    	then
    		echo "$username 已存在"
    	else
    		echo "$username 不存在,将被创建"
    		useradd $username
    		echo 123456 | passwd --stdin $username &> /dev/null
    	fi
    done
    
    tail /etc/passwd # 验证结果
    
    #!/bin/bash
    # 探测一个网段中存活的主机
    
    for ip in 192.168.42.{1..254}
    do
    	{
    	ping -c 3 -i 0.5 -w 2 $ip &> /dev/null
    					#3个包,每0.5秒发送一个,最多等待两秒
        if [ $? -eq 0 ]
        then
        	echo "$ip online" >> /opt/hostlist.txt
        else
        	echo "$ip offline" >> /opt/hostlist.txt
        fi
    	}&   # 大括号内的内容耗时长,后台运行
    done
    wait   # 等待上面的循环完成
    cat /opt/hostlist.txt
    
    #!/bin/bash
    # 实现生成只包含小写字母和数字的随机八位密码
    
    warehouse='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
    length=${#warehouse} # 获取warehouse长度
    
    for i in {1..8}
    {
            a+=${warehouse:$[$RANDOM % length]:1} 
            #随机数RANDOM按warehouse长度取随机值并取对应下标位置的一个字符拼接为变量a
    }
    
    echo "随机密码为 $a"
    
    #!/bin/bash
    #提示输入密码并验证,上限尝试五次
    
    passwd='123456'
    
    for i in {1..5}
    do
    	read -p "输入密码:" tmp
    	if [ "$tmp" -eq $passwd];then
    		echo "密码正确!"
    		exit 0   # exit是正常退出但可以指定返回的状态码
    	elif
    		echo "输入错误,还有$[ 5 - $i ]次机会!"
    done
    echo "机会用完,无法登录"
    exit 1 #登陆异常返回1
    
  • for循环的IFS

    #!/bin/bash
    IFS_OLD=$IFS #备份IFS
    IFS=$'\n' # 通过更改IFS的方法来按照自己的需求实现for循环分隔取值的方法
    for name in $(cat /opt/users.txt)
    do
    	echo $name
    done
    
    IFS=$IFS_OLD #还原IFS
    

    set | grep IFS # 查看所有的IFS

    #!/bin/bash
    IFS_OLD=$IFS
    IFS=$IFS':'
    
    for f in $(echo $PATH)
    do
    	echo "目录有:$f"
    	for FILE in $(ls $f) # $f/*,要考虑到判断时的相对路径和绝对路径的问题
    	do
    		if [ -f $f/$FILE ] && [ -x $f/$FILE ];then # [ -f $FILE -a -x $FILE ]
    			echo -e "\t$FILE 有执行权限"
    		fi
    	done
    done
    
    IFS=$IFS_OLD
    

while循环语句

  • 重复测试某个条件,只要条件成立则反复执行

    while 条件测试操作
    do
    	命令序列
    done
    
    #!/bin/bash
    # 创建20个stu用户,以后缀数字区分
    
    #for name in {1..20}
    name=1 #计数
    while [ $name -ge 0 -a $name -le 20 ]
    do
    	useradd stu$name
    	echo 123456 | passwd --stdin stu$name
    	let name++
    done
    
    #tail /etc/passwd
    
    #!/bin/bash
    #猜价格游戏
    
    CURRENT=$[RANDOM % 1000]
    
    a=1 # 控制循环退出条件
    num=0 # 次数计数变量
    while [ $a -eq 1 ]
    do
    	read -p "请输入你猜测的价格(0-999):" price
    	if [ $price -gt $CURRENT ];then
    		echo "猜高了,请重试!"
    		let num++
    	elif [ $price -lt $CURRENT ];then
    		echo "猜低了,请重试!"
    		let num++
    	elif [ $price -eq $CURRENT ];then
    		let num++
    		echo "恭喜你猜对了!正确的价格为 $price,你一共猜了 $num 次"
    		let a++
    	else
    		echo "输入有问题,程序退出"
    		exit 1
    	fi
    done
    
  • while的read按行读取

    while read line  # 或者cat users.txt | while read name则不需要重定向输入
    > do
    > echo $line
    > done < users.txt # 重定向输入给while
    
  • 分割文本50行一份,如果多出不满50行也算一个文件,分割出的文件按照源文件名+序号命名

    a=0 # a作为行数的标记
    num=1 # num作为文件的数目标记
    
    cat 文件 | while read line
    do
    	let a++
    	b=$[ $a % 50 ]
    	if [ $b -eq 0 ];then
    		echo $line >> /opt/文件$num
    		let num++
    	else
    		echo $line >> /opt/文件$num
    	fi
    done
    

until循环语句

  • 重复测试某个条件,只要条件不成立则反复执行

    until 条件表达式
    do
    	命令序列
    done
    
    #!/bin/bash
    # 循环10次
    
    a=1
    #while [ $a -ge 1 -a $a -le 10 ]
    #do
    #	echo $a
    #	let a++
    #done
    
    until [ $a -gt 10 ]
    do
    	echo $a
    	let a++
    done
    
    #!/bin/bash
    # 实现给输入的用户发送邮件消息
    
    # example: ./write.sh <USERNAME> [message]
    
    username=$1
    # 用于判断执行脚本的格式是否携带了位置参数
    if [ $# -lt 1 ];then		# 对脚本参数个数不满足条件的进行操作提示处理
    	echo "Usage: $0 <username> [<message>]"
    	exit 1
    fi
    
    #用于判断携带的用户名参数是否正确
    grep "^${username}:" /etc/passwd > /dev/null
    if [ $? -ne 0 ];then
    	echo "$username is not a user on this system."
    	exit 2
    fi
    
    #用户判断系统用户是否已登录
    who | grep "$username" > /dev/null
    #while [ $? -ne 0 ]
    do
    	echo "$username is not logged on."
    	sleep 10[]
    done
    
    # 所有条件满足,发送消息
    if [ ! -z "$msg" ];then
    	echo "执行命令:echo $msg | write $username"
    else
    	msg="hello $username,this is default message"
    	echo "执行命令:echo $msg | write $username"
    fi
    

循环的嵌套

for循环的嵌套

#!/bin/bash

for ((a=1; a<=5; a++))
do
	echo "外部循环:a=$a"
	for ((b=1; b<=5; b++))
	do
		if [ $b -eq 3 ];then
			#exit 2
			#break
			#continue
		fi
		echo -e "\t内部循环:b=$b"
	done
done
操作符作用
exit用于退出脚本进程
break [n]用于退出n层循环(n填入数字)
continue用于中止某次循环中的操作,不会完全中止整个循环命令
#!/bin/bash
# 输出九九乘法表

for ((a=1; a<=9; a++))
do
        for ((b=1; b<=$a; b++))
        do
                echo -n -e "$b*$a=$[ $a*$b ]\t"
        done
        echo ""
done

while的嵌套

#!/bin/bash
# 循环5x5次

a=1
while [ $a -le 5 ]
do
	b=1 # 每次循环开始将内部循环b的初始值置为1
	echo "外部循环:a=$a"
	echo "此时b=$b"
	while [ $b -le 5 ]
	do
		echo "   内部循环:b=$b"
		let b++
	done
	let a++
done
#!/bin/bash
# while嵌套的方式输出九九乘法表

a=1
while [ $a -le 9 ]
do
        b=1
        while [ $b -le $a ]
        do
                echo -ne "$b*$a=$[ $a*$b ]\t"
                let b++
        done
        let a++
        echo ""
done

输出指定图形

#!/bin/bash
# 直线
for ((a=1; a<=20; a++)) # 长为20
do
	echo -n "*"
done
echo ""
#!/bin/bash
# 矩形
for ((a=1; a<=10; a++)) #控制行数,此处为宽
do
	for((b=1; b<=20; b++)) #控制列数,此处为长
	do
		echo -n "*"
	done
	echo ""
done
#!/bin/bash
# 空心矩形
for ((a=1; a<=20; a++)) #输出上边
do
	echo -n "*"
done
echo ""

for ((a=1; a<=8; a++))
do
	for ((b=1; b<=20; b++))
	do
		if [ $b -eq 1 -o $b -eq 20 ];then #只在每行行首行尾打印*
			echo -n "*"
		else
			echo -n " " #打印空格
		fi
	done
	echo ""
done

for ((a=1; a<=20; a++)) #输出下边
do
	echo -n "*"
done
echo ""
#!/bin/bash
# 直角三角形(直角在左下)
for ((a=1; a<=10; a++)) # for ((a=9; a>=0; a--))
do
	for ((b=1; b<=a; b++)) # for ((b=9; b>=a; b--)),用a的值控制每行输出的*的个数
	do
		echo -n "*"
	done
	echo ""
done

# 直角三角形(直角在左上)
for ((a=1; a<=10; a++)) # for ((a=9; a>=0; a--))
do
	for ((b=10; b>=a; b--)) # for ((b=1; b<=a; b++)),倒序b的值控制每行*的个数递减
	do
		echo -n "*"
	done
	echo ""
done

# 直角三角形(直角在右下)
for ((a=1; a<=10; a++))
do
	for ((b=10; b>=a; b--)) #先输出一个左上直角的空格三角形
	do
		echo -n " "
	done
	for ((c=1; c<=a; c++)) #输出一个右下直角的*三角形,两个输出同时进行
	do
		echo -n "*"
	done
	echo ""
done

# 直角三角形(直角在右上),与上例同理
for ((a=1; a<=10; a++))
do
	for ((c=1; c<=a; c++))
	do
		echo -n " "
	done
	for ((b=10; b>=a; b--))
	do
		echo -n "*"
	done
	echo ""
done

# 等腰三角形
for ((a=1; a<=9; a++))
do
        for ((b=9; b>=a; b--)) #先输出一个左上直角的空格三角形
        do
                echo -n " "
        done
        i=$[($a*2)-1] #按每行的*个数输出,按行组成等腰三角形
        for j in $(seq 1 $i)
        do
                echo -n "*"
        done
        echo ""
done

# 等腰三角形
for ((a=1; a<=10; a++))
do
	for ((b=10; b>=a; b--)) #先输出一个左上直角的空格三角形
	do
		echo -n " "
	done
	for ((c=1; c<=a; c++)) #输出一个右下直角的*三角形
	do
		echo -n "*"
	done
	for ((d=1; d<a; d++)) #输出一个左下小一号的直角的*三角形,组合
	do
		echo -n "*"
	done
	echo ""
done
#!/bin/bash
# 平行四边形
for ((a=1; a<=6; a++))
do
	for ((b=6; b>=a; b--)) #先输出一个左上直角的空格三角形
    do
    	echo -n " "
    done
    for ((c=1; c<=6; c++)) #每行输出6个*
    do
    	echo -n "*"
    done
    echo ""
done
#!/bin/bash
# 梯形
for ((a=1; a<=6; a++))
do
	for ((b=6; b>=a; b--)) #先输出一个左上直角的空格三角形
    do
    	echo -n " "
    done
    for ((c=1; c<=6+a; c++)) #每行输出6+a个*
    do
    	echo -n "*"
    done
    echo ""
done
#!/bin/bash
# 菱形
for ((a=1; a<=6; a++))
do
	for ((b=6; b>=a; b--)) #先输出一个左上直角的空格三角形
	do
		echo -n " "
	done
	i=$[($a*2)-1] # 输出一个等腰三角形
	for j in $(seq 1 $i)
	do
		echo -n "*"
	done
	echo ""
done
for ((a=1; a<=5; a++))
do
	for ((b=1; b<=a+1; b++)) #输出一个左下直角的空格三角形
	do
		echo -n " "
	done
	i=$[11-$a*2] # 输出一个朝下的小一号的等腰三角形
	for ((c=i; c>0; c--))
	do
		echo -n "*"
	done
	echo ""
done
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值