Shell循环语句

  • 2019-11-19
  • 29
  • 0
  • 0

for循环

for循环一般格式为:

for var in item1 item2 ... itemN
do
    command1
    command2
    ...
    commandN
done

 

两种不同的效果:

[root@localhost SHELL]# vim for1.sh
#!/bin/bash
for year in 1 2 3 4
do
        echo 你 var 岁了
done

[root@localhost SHELL]# bash for1.sh 
你 var 岁了
你 var 岁了
你 var 岁了
你 var 岁了
[root@localhost SHELL]# vim for1.sh
#!/bin/bash
for year in 1 2 3 4
do
        echo 你 $var 岁了
done

[root@localhost SHELL]# bash for1.sh 
你 1 岁了
你 2 岁了
你 3 岁了
你 4 岁了

列表中的复杂值,可以使用 引号或转义字符”/”来加以约束

[root@localhost SHELL]# vim for2.sh
#!/bin/bash
for var in a1 b1 "c1 d1" e2 "hello world" I\'s a22
do
        echo $var
done

从变量中取值

[root@localhost SHELL]# vim for3.sh
#!/bin/bash
list="a b c d"
for i in $list
do
        echo $i
done

从命令中取值默认会以空格做分隔

[root@localhost SHELL]# vim for4.sh
#!/bin/bash
for i in `cat /etc/hosts`
do
        echo $i
done
# 测试结果
[root@localhost SHELL]# bash for4.sh 
127.0.0.1
localhost
localhost.localdomain
localhost4
localhost4.localdomain4
::1
localhost
localhost.localdomain
localhost6
localhost6.localdomain6

自定义shell分隔符

默认情况下,base shell会以空格、制表符、换行符做为分隔符。通过IFS来自定义为分隔符

指定单个字符做分隔符:
IFS=:        #以:冒号做分隔符

可以指定多个
如 :IFS=’\n’:;”        #这个赋值会将反斜杠、n、冒号、分号和双引号作为字段分隔符。

 注:$’\n’与’\n’时的区别

IFS=’\n’    # 将字符\和字符n作为IFS的换行符。

IFS=$’\n’   # 正真的使用换行符做为字段分隔符。

# 指定以 回车 做为 for语句的分隔符
[root@localhost SHELL]# vim for5.sh
#!/bin/bash
IFS=$'\n'
for i in `cat /etc/hosts`
do
        echo $i
done
[root@localhost SHELL]# bash for5.sh 
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6

C语言风格的for

[root@localhost SHELL]# vim for6.sh
#!/bin/bash
for ((i=0; i<=5; i++))
do
        echo $i
done
# 执行结果
[root@localhost SHELL]# bash for6.sh 
0
1
2
3
4
5

多个变量。 同时输出1-9的升序和降序

# 第一种(乱写的)
#!/bin/bash
for i in {1..9}
do
        echo $i         `expr 10 - $i`
done
# 第二种(感觉更好!!!)
#!/bin/bash
for ((a=1, b=9; a<10; a++,b--))
do
        echo $a         $b
done
# 运行结果都一样
[root@localhost SHELL]# bash for7.sh 
1 9
2 8
3 7
4 6
5 5
6 4
7 3
8 2
9 1

while循环

重复测试指令的条件,只要条件成立就反复执行对应的命令操作,直到命令不成立或为假

while循环用于不断执行一系列命令,也用于从输入文件中读取数据;命令通常为测试条件。其格式为:

例1:降序输出10到1的数字
while condition
do
    command
done

第一种方法(感觉更好用):

[root@localhost SHELL]# vim while1.sh
#!/bin/bash
var=10
while [ $var -gt 0 ]
do
        echo $var
        var=$[$var-1]
done

第二种方法:

自增操作  let var++ 

自减操作  let var– 

[root@localhost SHELL]# vim while1.sh
#!/bin/bash
int=10 
while ((int<=10)) 
do 
        echo $int let "int--" 
done
# 执行结果:
[root@localhost SHELL]# bash while1.sh 
10
9
8
7
6
5
4
3
2
1

例2:输出如下所示两数相乘的效果

1 * 1 = 1
2 * 2 = 4
3 * 3 = 9
4 * 4 = 16
5 * 5 = 25
6 * 6 = 36
7 * 7 = 49
8 * 8 = 64
9 * 9 = 81

第一种方法(还是感觉这种方法用起来比较顺手):

[root@localhost SHELL]# vim while2.sh
#!/bin/bash
var=1
while [ $var -lt 10 ]
do
        echo "$var * $var = $[$var*$var]"
        var=$[$var+1]
done

第二种方法:

#!/bin/bash
num=1
while [ $num -lt 10 ]
do
        sum=$((  $num * $num ))
        echo  "$num * $num = $sum"
        let (num++)
        #((num++))
done
# 运行结果都一样
[root@localhost SHELL]# bash while2.sh 
1 * 1 = 1
2 * 2 = 4
3 * 3 = 9
4 * 4 = 16
5 * 5 = 25
6 * 6 = 36
7 * 7 = 49
8 * 8 = 64
9 * 9 = 81

until 循环

until 循环执行一系列命令直至条件为 true 时停止。

until 循环与 while 循环在处理方式上刚好相反。

一般 while 循环优于 until 循环,但在某些时候—也只是极少数情况下,until 循环更加有用。

until 语法格式:

until condition
do
    command

如果返回值为 false,则继续执行循环体内的语句,否则跳出循环。

演示:

#!/bin/bash
a=1
until [ ! $a -lt 10 ]
    do
        echo "$a"
        let "a++"
done

执行输出结果:

[root@shuai ~]# ./until.sh 
1
2
3
4
5
6
7
8
9

嵌套循环

编写脚本的思路

  1. 明确脚本的功能
  2. 编写脚本时会使用到那些命令 ?  useradd    passwd   for
  3. 把变化的数据使用变量表示
  4. 选择适合的流程控制  (选择 、 循环 、分支)

批量添加用户

例1:批量添加 usernames.txt文件内的用户,并设置密码为123456

[root@localhost SHELL]# vim for-useradd.sh
#!/bin/bash
for name in `cat /root/SHELL/usernames.txt`
do
        id $name &> /dev/null
        if [ $? -ne 0 ];        then
                useradd $name
                echo '123456' | passwd --stdin $name &> /dev/null
                echo "用户 $name 创建成功"
        else
                echo "用户 $name 已存在"
        fi
done
# 写入用户名
[root@localhost SHELL]# vim usernames.txt
shuaishuaishuai
guoguoguo
# 运行结果
[root@localhost SHELL]# bash for-useradd.sh 
用户 shuaishuaishuai 创建成功
用户 guoguoguo 创建成功
[root@localhost SHELL]# bash for-useradd.sh 
用户 shuaishuaishuai 已存在
用户 guoguoguo 已存在
# 查看用户是否创建成功
[root@localhost SHELL]# id shuaishuaishuai
uid=1007(shuaishuaishuai) gid=1007(shuaishuaishuai) 组=1007(shuaishuaishuai)
[root@localhost SHELL]# id guoguoguo
uid=1008(guoguoguo) gid=1008(guoguoguo) 组=1008(guoguoguo)

例2:创建一个脚本 , 此脚本能实现为系统创建本地用户, 并且这些用户的用户名来自一个包含用户名列表的文件。

同时满足下列要求:

  • 此脚本要求提供一个参数,此参数就是包含用户名列表的文件
  • 如果没有提供参数,此脚本应该给出下面的提示信息Usage: /root/SHELL/usernames.txt 然后退出并返回相应的值
  • 如果提供一个不存在的文件名,此脚本应该给出下面的提示信息Input file not found 然后退出并返回相应的值
  • 创建的用户登录shell 为/bin/false
  • 此脚本不需要为用户设置密码
[root@localhost SHELL]# vim while-useradd.sh
#!/bin/bash
if [ $# -eq 0 ];        then
        echo 'Usage: /root/SHELL/usernames.txt'
        exit 1
fi
if [ ! -e $1 ];         then
        echo 'Input file not found'
        exit 1
fi
while read username
do
        useradd -s /bin/false $username
done < $1
# 写入用户名
[root@localhost SHELL]# vim usernames.txt
SHUAI
GUO
# 测试结果
[root@localhost SHELL]# bash while-useradd.sh 
Usage: /root/SHELL/usernames.txt
[root@localhost SHELL]# bash while-useradd.sh woc?
Input file not found
[root@localhost SHELL]# bash while-useradd.sh /root/SHELL/usernames.txt
# 查看用户是否创建成功
[root@localhost SHELL]# tail -2 /etc/passwd
SHUAI:x:1009:1009::/home/SHUAI:/bin/false
GUO:x:1010:1010::/home/GUO:/bin/false

打印九九乘法表

[root@localhost SHELL]# vim 99.sh
#!/bin/bash
for i in `seq 9`
do
        for j in `seq $i`
        do
                echo -n "$i*$j=$[$i*$j] "
        done
        echo
done
# 运行结果
[root@localhost SHELL]# bash 99.sh 
1*1=1  
2*1=2 2*2=4  
3*1=3 3*2=6 3*3=9  
4*1=4 4*2=8 4*3=12 4*4=16  
5*1=5 5*2=10 5*3=15 5*4=20 5*5=25  
6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36  
7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49  
8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64  
9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81  

实战-3个shell脚本实战

实战1:将/var/log/目录下所有的日志文件全自动打包到/opt/backup

[root@localhost SHELL]# vim log-back.sh
#!/bin/bash
LOG_DIR=/var/log/
SRC_DIR=/opt/backup/`date +%Y%m%d`

if
[ ! -d $SRC_DIR ];      then
        mkdir -p $SRC_DIR
fi
for i in `find $LOG_DIR -name "*.log"`
do
        tar zcvf $i.tgz $i 2>&1 > /dev/null
done
mv $LOG_DIR*.tgz $SRC_DIR
ls -lh $SRC_DIR
echo '打包完成'

实战2:找出192.168.1.*网段中,服务器已经关机的IP地址

[root@localhost SHELL]# vim ping.sh
#!/bin/bash
for i in `seq 1 255`
do
        ping -c 3 192.168.1.$i &> /dev/null
        if [ $? -ne 0 ];        then
                echo 192.168.1.$i is shutdown
        fi
done

实战3:批量创建帐号并生成随机密码

[root@localhost SHELL]# vim useradd.sh
#!/bin/bash
for i in user{1..10}
do
        useradd $i
        pass=`date +%s | md5sum | cut -c 1-8`
        sleep 1
        echo "$i:$pass" >> /tmp/passwd.log
        echo $pass | passwd --stdin $i > /dev/null 2>&1
        if [ $? -eq 0 ];        then
                echo "create $i is successfully!"
        else
                echo "create $i is failed"
        fi
done
# 运行结果
[root@localhost SHELL]# bash useradd.sh 
create user1 is successfully!
create user2 is successfully!
create user3 is successfully!
create user4 is successfully!
create user5 is successfully!
create user6 is successfully!
create user7 is successfully!
create user8 is successfully!
create user9 is successfully!
create user10 is successfully!

评论

还没有任何评论,你来说两句吧

发表评论

:zhenbang: :yiwen: :yinyue: :yinxian: :yi: :xxyl: :xinsui: :xiaonian: :weiqu: :tushe: :tu: :taiyang: :taikaixin: :shuijiao: :shenli: :shengqi: :ruo: :qianbi: :qian: :pen: :neng: :mianqiang: :meigui: :lu: :liwu: :kuanghan: :ku: :kaixin: :jinya: :jiku: :huaxin: :huaji: :hu: :heixian: :hehe: :han: :haha: :haha2: :guai: :dangao: :damuzhi: :daku: :chabei: :caihong: :bugaoxing: :bishi: :aixin: :a: :OK: :) :(