shell语句中的循环(for、while、until)【九九乘法表、空心等腰三角形、空心菱形、给指定用户发送消息】

shell语句中的循环

一、for循环

【1】for语句的结构

读取不同的变量值,用来诸葛执行同一组命令。

【2】注意事项

(1)for循环中的变量可以是一个也可以是多个。
(2)for循环中语句可以为语句体, 语句体外加大括号"do done"将参加循环的语句括起来。
(3)for循环中的"单次表达式"、"条件表达式"和"循环体语句"都是选择项, 即可以缺省成只剩下“;”的空语句。

【3】语法:
(1)第一种语法格式:
for 变量名 in 取值列表
do
  命令序列
done
1)结构示意图

在这里插入图片描述

2)举例说明

批量添加用户,用户名存放在文件中,每行一个,初始密码设置为000000,执行结果之后重新写一个删除脚本。
创建用户名存放文件

[root@localhost opt]# vim users.txt 
zhaoqian
sunli
zhouwu
zhengwang

编写shell脚本

[root@localhost opt]# vim users.sh
#!/bin/bash
list=$(cat /opt/users.txt)
for user in $list
 do
  useradd  $user
  echo "000000" | passwd --stdin $user >/dev/null
  echo "创建 $user 成功!" 
 done
 
[root@localhost opt]# sh users.sh 
[root@localhost opt]# tail -5 /etc/passwd
zhang:x:1000:1000:zhang:/home/zhang:/bin/bash
zhaoqian:x:1001:1001::/home/zhaoqian:/bin/bash
sunli:x:1002:1002::/home/sunli:/bin/bash
zhouwu:x:1003:1003::/home/zhouwu:/bin/bash
zhengwang:x:1004:1004::/home/zhengwang:/bin/bash

批量删除用户shell脚本

[root@localhost opt]# vim userdel.sh 
#!/bin/bash
list=$(cat /opt/users.txt)
for udel in $list
do
  userdel $udel
  echo "${udel} is deleted!"   
done
[root@localhost opt]# sh userdel.sh 
zhaoqian is deleted!
sunli is deleted!
zhouwu is deleted!
zhengwang is deleted!
[root@localhost opt]# tail -5 /etc/passwd
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
zhang:x:1000:1000:zhang:/home/zhang:/bin/bash
(2)第二种语法格式:
for ((临时变量=取值;变量满足的条件;变量增/减))
do
  命令序列
done
1)语法结构示意图

在这里插入图片描述

2)举例说明

列出1-10的数字

[root@localhost opt]# vim count.sh
#!/bin/bash
for ((i=1;i<=10;i++))
do
  echo "$i"
done
[root@localhost opt]# sh count.sh 
1
2
3
4
5
6
7
8
9
10

求出1-100的和

[root@localhost opt]# vim sum.sh
#!/bin/bash
sum=0
for ((i=1;i<=100;i++))
do
#  sum=`expr $i + $sum`
   let sum+=$i
done
  echo "$sum"
[root@localhost opt]# sh sum.sh 
5050

求出 1-100的偶数和

[root@localhost opt]# vim sum02.sh
#!/bin/bash
sum=0
for ((i=0;i<=100;i+=2))
do
  let sum+=$i
done
  echo "$sum"
[root@localhost opt]# sh sum02.sh 
2550

求出1-100的奇数和

[root@localhost opt]# vim sum01.sh 
#!/bin/bash
sum=0
for ((i=1;i<=100;i+=2))
do
  let sum+=$i
done
  echo "$sum"
[root@localhost opt]# sh sum01.sh 
2500

二、while循环

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

【1】语法格式
while [ 条件测试操作 ]
do
  命令序列
  let 变量++或变量--
done
【2】注意事项

while 循环:先判断后执行,可能出现一次都没有循环的情况;变量的初始化是在循环体外,循环条件判断是在while [ 条件 ]中进行,而变量的更新是在do done中进行更新。

【3】举例说明

批量创建文件,要求以stu开头,以.txt结尾,1-10个文件,如stu1。

[root@localhost opt]# vim name.sh 
#!/bin/bash
name="stu"
hz=".txt"
i=1
while [ $i -le 10 ]
do
  touch ${name}${i}${hz} /opt
  let i++
done
[root@localhost opt]# sh name.sh 
[root@localhost opt]# ls
stu1.txt  stu4.txt  stu7.txt
stu2.txt  stu5.txt  stu8.txt
stu10.txt  stu3.txt  stu6.txt  stu9.txt

显示出1-100不能被3整除的数

[root@localhost opt]# vim count1.sh
#!/bin/bash
i=1
while [ $i -le 10 ] 
do
  if [ `expr $i % 3` -ne 0 ];then
  echo "$i"
  fi
  let i++
done
[root@localhost opt]# sh count1.sh 
1
2
4
5
7
8
10

三、经典案例

【1】九九乘法表
[root@localhost opt]# vim jiujiu.sh 
#!/bin/bash
for ((i=1;i<=9;i++))
do
  for ((j=1;j<=$i;j++))
  do
    num=$(expr $i \* $j)
    printf "${j}*${i}=${num} \t"
  done
    echo ""
done
[root@localhost opt]# sh jiujiu.sh 
1*1=1 	
1*2=2 	2*2=4 	
1*3=3 	2*3=6 	3*3=9 	
1*4=4 	2*4=8 	3*4=12 	4*4=16 	
1*5=5 	2*5=10 	3*5=15 	4*5=20 	5*5=25 	
1*6=6 	2*6=12 	3*6=18 	4*6=24 	5*6=30 	6*6=36 	
1*7=7 	2*7=14 	3*7=21 	4*7=28 	5*7=35 	6*7=42 	7*7=49 	
1*8=8 	2*8=16 	3*8=24 	4*8=32 	5*8=40 	6*8=48 	7*8=56 	8*8=64 	
1*9=9 	2*9=18 	3*9=27 	4*9=36 	5*9=45 	6*9=54 	7*9=63 	8*9=72 	9*9=81 	
【2】空心等腰三角形
[root@localhost opt]# vim dengyao01.sh 
#!/bin/bash
num=9
for ((i=1;i<=$num;i++))
do
  for((j=1;j<=$num-$i;j++))
  do
  echo -n "  "
  done
  for((j=1;j<=$i\*2-1;j++))
  do
   if [ $j -eq 1 -o $j -eq `expr 2 \* $i - 1` -o $i -eq 9 ];then
   echo -ne " *"
   else
   echo -n "  "
   fi
  done
 echo " "
done
[root@localhost opt]# sh dengyao01.sh 
                 * 
               *   * 
             *       * 
           *           * 
         *               * 
       *                   * 
     *                       * 
   *                           * 
 * * * * * * * * * * * * * * * * * 
【3】实心等腰三角形
[root@localhost opt]# vim dengyao.sh 
#!/bin/bash
num=9
for ((i=1;i<=$num;i++))
do
  for((j=1;j<=$num-$i;j++))
  do
  echo -n "  "
  done
  for((j=1;j<=$i\*2-1;j++))
  do
   echo -ne " *"
  done
 echo " "
done
[root@localhost opt]# sh dengyao.sh 
                 * 
               * * * 
             * * * * * 
           * * * * * * * 
         * * * * * * * * * 
       * * * * * * * * * * * 
     * * * * * * * * * * * * * 
   * * * * * * * * * * * * * * * 
 * * * * * * * * * * * * * * * * * 

【4】实心菱形
[root@localhost opt]# vim lingxing.sh 
#!/bin/bash
read -p "奇数层数:" num
if [ $(expr $num % 2) -eq 0 ];then
  echo "请输入奇数!"
###########退出,不执行下面的循环#################
  exit 1
else
#################上面一部分加中间一行,相当于实心等腰三角形##########
for((i=1;i<=num/2+1;i++))
do
  for((b=num/2;b>=i;b--))
    do
      echo -n "  "
    done
  for((a=1;a<=i*2-1;a++))
    do
      echo -n " *"
    done
  echo ""
done
####################下面一部分,相当于倒立的实心等腰三角形############
for((j=1;j<=num/2;j++))
do
  for((d=1;d<=j;d++))
  do
    echo -n "  "
  done
  for((e=num-2;e>=j*2-1;e--))
  do
    echo -n " *"
  done
  echo ""
done
fi
[root@localhost opt]# sh lingxing.sh 
奇数层数:19
                   *
                 * * *
               * * * * *
             * * * * * * *
           * * * * * * * * *
         * * * * * * * * * * *
       * * * * * * * * * * * * *
     * * * * * * * * * * * * * * *
   * * * * * * * * * * * * * * * * *
 * * * * * * * * * * * * * * * * * * *
   * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * *
       * * * * * * * * * * * * *
         * * * * * * * * * * *
           * * * * * * * * *
             * * * * * * *
               * * * * *
                 * * *
                   *
【5】空心菱形
[root@localhost opt]# vim lingxing01.sh 
#!/bin/bash
read -p "奇数行数:" num
if [ $(expr $num % 2) -eq 0 ];then
  echo "请输入奇数!"
  exit 1
else
——————————————上面一部分加中间一行————————————————
for((i=1;i<=num/2+1;i++))
do
  for((b=num/2;b>=i;b--))
    do
      echo -n "  "
    done
  for((a=1;a<=i*2-1;a++))
    do
#############控制空心的条件if循环#####################
    if [ $a -eq 1 -o $a -eq `expr $i \* 2 - 1` ];then
      echo -n " *"
    else
      echo -n "  "
    fi
############################################
    done
  echo ""
done
——————————————————下面一部分——————————————
for((j=1;j<=num/2;j++))
do
  for((d=1;d<=j;d++))
  do
    echo -n "  "
  done
  for((e=num-2;e>=j*2-1;e--))
  do
###################倒立的等腰三角形空心控制,注意条件#########
    if [ $e -eq `expr $num - 2` -o $e -eq `expr $j \* 2 - 1` ];then
    echo -n " *"
    else
      echo -n "  "
    fi
#######################################################
  done
  echo ""
done
fi
[root@localhost opt]# sh lingxing01.sh 
奇数行数:19
                   *
                 *   *
               *       *
             *           *
           *               *
         *                   *
       *                       *
     *                           *
   *                               *
 *                                   *
   *                               *
     *                           *
       *                       *
         *                   *
           *               *
             *           *
               *       *
                 *   *
                   *

四、转义字符应用

【1】概念

转义字符是一种特殊的字符常量。转义字符以反斜线""开头,后跟一个或几个字符。转义字符具有特定的含义,不同于字符原有的意义,故称“转义”字符。例如,在前面各例题printf函数的格式串中用到的“\n”就是一个转义字符,其意义是“回车换行”。转义字符主要用来表示那些用一般字符不便于表示的控制代码。

【2】常见转义参数含义

在shell脚本中要输转义字符使用【printf】命令或者【echo -ne】其中
-n 不要在最后自动换行
-e 若字符串中出现以下字符,则特别加以处理,而不会将它当成一般

\n 回车换行 
\t 横向跳到下一制表位置 
\v 竖向跳格 垂直制表符 
\b 退格 
\r 回车 
\f 走纸换页 
\\ 反斜线符"\" 
\' 单引号符 
\a 鸣铃 
\ddd 1~3位八进制数所代表的字符 
\xhh 1~2位十六进制数所代表的字符 
广义地讲,c语言字符集中的任何一个字符均可用转义字符来表示。
\ddd和\xhh正是为此而提出的。ddd和hh分别为八进制和十六进制的ascii代码。
如\101表示字?quot;a" ,\102表示字母"b",\134表示反斜线,\xoa表示换行等。

五、until循环

重复测试某个条件,只要条件不成立则反复执行,注意是条件不成立反复执行,与while循环正好相反。

【1】语法格式

until [ 测试条件 ]#########注意,这儿的条件是对于某个事件不成立的条件
do
命令序列
let 变量++或变量–
done

【2】举例说明
(1)通过until循环计算1-50的和
[root@localhost opt]# vim sum.sh 
#!/bin/bash
i=1
sum=0
###############不成立的条件##########
until [ $i -eq 51 ] 
do
#  sum=`expr $i + $sum`
   let sum+=$i
   let i++
done
  echo "1-50的和是:$sum"
[root@localhost opt]# sh sum.sh 
1-50的和是:1275
(2)给指定用户发送消息

1)要求:为指定用户发送消息,若用户不在线(未登录系统),则每5秒钟(为了实验效果缩短时间)试一次,直到用户登录系统后再发送在线消息,用户名与消息通过位置参数传递给脚本。
2)分析:
首先,用户的姓名属于系统用户(可以使用cat命令查看/etc/passwd文件),
其次,用户是否在线可以使用命令who查看,这儿是一个循环,每5秒查看一次,
然后,发送消息可以输出消息 echo “你好!” | write 用户,
最后,位置参数有用户名和消息两部分,所以位置参数大于1
(3)案例操作

[zhangsan@localhost ~]$echo "你好" | write "root"
[root@localhost opt]# 
Message from zhangsan@localhost.localdomain on pts/1 at 12:21 ...
你好
EOF
[root@localhost opt]# 
[root@localhost opt]# vim xiaoxi.sh
#!/bin/bash
username=$1
#参数不能小于1,如果为空退出,不执行后面的命令
if [ $# -lt 1 ];then
  echo "格式:`basename $0` <用户名> <消息内容>"
  exit 1
fi
#验证用户是否属于系统用户,注意then后面是空格,冒号
if grep "^$username" /etc/passwd > /dev/null;then :
else
  echo "没有这个用户"  
  exit 2
fi
#测试用户是否在线,如果不在线,5秒联系一次,until是条件不成立则执行循环,如果成立不执行循环
until who | grep "$username" > /dev/null
do
  echo "用户不在线!"
  sleep 5
done
#发送消息
echo "$2" | write "$username"

[root@localhost opt]# sh xiaoxi.sh zhangsan nihaoa
Message from root@localhost.localdomain on pts/0 at 13:04 ...
nihaoa
EOF
[root@localhost opt]# sh xiaoxi.sh lisi dudu
用户不在线!
用户不在线!
用户不在线!
[root@localhost opt]# sh xiaoxi.sh aiya dudu
没有这个用户
[root@localhost opt]# sh xiaoxi.sh
格式:xiaoxi.sh <用户名> <消息内容>
  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值