shell—for循环

shell—for循环

1.for循环基本概述

1.1 什么是循环

脚本在执行任务的时候,总会遇到需要循环执行的时候,比如说我们需要脚本每隔五分钟执行一次ping操作,除了计划任务,我们还可以使用循环语句

1.2 什么是for循环

很多人把for循环叫做条件循环,因为for循环的次数和给予的条件是成正比的,也就是给你几个条件,就会循环几次

2.for循环基础语法

1.for循环基础语法示例

#for循环语法                               for循环示例(默认以空格做分隔)
for  变量名 in [ 取值列表 ]                       for var in file1 file2 file3
do                                              do
     循环体                                            echo the text is $var
done                                            done

2.for循环基本使用示例,列表中的复杂值,可以使用引号或转义字符"/"来加以约束

[root@manage for]# cat for02.sh 
#!/bin/bash
for var in file1 "file2 file3" file4 "hello world"
do
    echo the text is $var
done

[root@manage for]# sh for02.sh 
the text is file1
the text is file2 file3
the text is file4
the text is hello world


[root@manage for]# cat for03.sh 
#!/bin/bash

#下面两种写法意思相同
#for var in {1..5}
for var in $(seq 5)
do
    echo $var
done


[root@manage for]# sh for03.sh 
1
2
3
4
5

[root@manage for]# cat for04.sh 
#!/bin/bash
for var in file1 file\'2 I\'s
do
    echo $var
done

[root@manage for]# sh for04.sh 
file1
file'2
I's


3.for循环,从变量中取值

[root@manage for]# cat for05.sh 
#!/bin/bash
list="file1 file2 file3"
for i in $list
do
   echo "$i"
done


4.for循环,从文件中取值

[root@manage for]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

#如果是行文件,会直接以空格为分隔符,按列打印出来
[root@manage for]# cat for06.sh 
for i in $(cat /etc/hosts)
do
        echo $i
done

[root@manage for]# sh for06.sh 
127.0.0.1
localhost
localhost.localdomain
localhost4
localhost4.localdomain4
::1
localhost
localhost.localdomain
localhost6
localhost6.localdomain6

5.for循环基本使用示例,自定义shell分隔符,默认情况以空格作为分隔符,通过IFS来自定义为分隔符

#以冒号做分隔符                        IFS=:
#以冒号、分号和双引号作为字段分隔符       IFS=:;"
#以换行符作为字段分隔符                 IFS=$'\n'

[root@manage for]# cat for06.sh 
#!/bin/bash
IFS=$'\n'
for i in $(cat /etc/hosts)
do
        echo $i
        sleep 1
done

[root@manage for]# sh for06.sh 
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6


#读取文件中信息,并且以冒号为分隔符
[root@manage for]# cat for07.sh 
#!/bin/bash
IFS=:  #以冒号做为分隔符
list=`head -1 /etc/passwd`
for i in $list
do
    echo $i
done

[root@manage for]# sh for07.sh 
root
x
0
0
root
/root
/bin/bash

6.for循环基本使用示例,C语言风格的for

#语法格式
for  (( i=0;i<10;i++))
do
     commands
done

[root@manage for]# cat for08.sh 
#!/bin/bash
for  (( i=0;i<10;i++))
do
     echo num is $i
done

[root@manage for]# sh for08.sh 
num is 0
num is 1
num is 2
num is 3
num is 4
num is 5
num is 6
num is 7
num is 8
num is 9


#常规写法
[root@manage for]# cat for09.sh 
#!/bin/bash
a=1
b=9
for i in $(seq 9)
do
    echo num is  $a $b
    let a++
    let b--
done

[root@manage for]# sh for09.sh 
num is 1 9
num is 2 8
num is 3 7
num is 4 6
num is 5 5
num is 6 4
num is 7 3
num is 8 2
num is 9 1


#c语言的写法
[root@manage for]# cat for10.sh 
#!/bin/bash
for (( a=1,b=9;a<10;a++,b-- ))
do
         echo num is $a $b
done

[root@manage for]# sh for10.sh 
num is 1 9
num is 2 8
num is 3 7
num is 4 6
num is 5 5
num is 6 4
num is 7 3
num is 8 2
num is 9 1

3.for循环练习题

需求1:用for循环探测某个网段主机存活状态,将存活的主机存入ok.txt

[root@manage for]# cat for11.sh 
#!/bin/bash

for i in {1..254}
do
     #加{}&并行处理
     {
     ip=10.0.0.$i
     ping 10.0.0.$i -W1 -c1 &>/dev/null
     if [ $? -eq 0 ];then
           echo "$ip 存活"
     fi
     }&
done
     wait   #上面循环执行完后在退出

需求2:判断主机存活状态,判断三次,如果三次都失败,则退出,将结果输出到文件中

[root@manage for]# cat for12.sh 
#!/bin/bash
for i in {1..254}
do
     {
     ip=10.0.0.$i
     ping 10.0.0.$i -W1 -c1 &>/dev/null
     if [ $? -eq 0 ];then
           echo "$ip 存活" >> ok.txt
     else
           for j in {1..3}
           do
                 ping 10.0.0.$i -W1 -c1 &>/dev/null
                 if [ $? -eq 0 ];then
                       echo "$ip 存活" >> ok.txt
                 else  
                       echo "$ip 不存活" >> err.txt
                 fi
           done
     fi
      }&
done
     wait   #上面循环执行完后在退出

需求3:有2个文件,一个ip文件,一个端口文件,探测ip的那个端口通

    现在有一个ip.txt的文件,里面有很多IP地址。
	还有一个port.txt的文件,里面有很多端口号。
	现在希望对ip.txt的每个IP地址进行端口的探测,探测的端口号来源于port.txt文件中
	最后将开放的端口和IP保存到一个ok.txt文件。
	
#需要安装nc命令:yum install nc -y
#用nc探测,结果输出echo $?=0,则端口为通,如果不为0则为不通
nc -z -w 1 10.0.0.201 22   
[root@manage for]# cat ip.txt 
10.0.0.1
10.0.0.2
10.0.0.3
10.0.0.4
10.0.0.5
10.0.0.6
10.0.0.7
10.0.0.8
10.0.0.201
172.16.1.5
192.168.10.1
192.168.10.99

[root@manage for]# cat port.txt 
80
22
8080
9000
3306
23
443
6379
10050
10051
10052


[root@manage for]# cat for13.sh 
#!/bin/bash
#遍历文件中的ip地址
for ip in $(cat ip.txt)
do
         {
         #第二次循环,遍历文件中的端口
         for port in $(cat port.txt)
         do
              #探测ip与端口的存活状态
              nc -z -w 1 $ip $port &>/dev/null
               if [ $? -eq 0 ];then
                    echo "$ip$port端口存活"
               fi
         done
         }&
done
         wait

[root@manage for]# sh for13.sh 
10.0.0.201 的 80端口存活
10.0.0.201 的 22端口存活
10.0.0.201 的 3306端口存活
10.0.0.201 的 10050端口存活
10.0.0.201 的 10051端口存活
10.0.0.201 的 10052端口存活
10.0.0.1 的 443端口存活
10.0.0.1 的 10050端口存活

需求4:获取系统的所有用户并输出

效果如下:
This is 1 user: root
This is 2 user: bin
This is 3 user: daemon
This is 4 user: adm
...............
	1.怎么获取所有的用户   awk -F ":" '{print $1}'
	2.遍历/etc/passwd 这个文件
	3.如何让数字的编号进行自增
	
[root@manage for]# cat for14.sh 
#!/bin/bash
i=1
for user in $(awk  -F ':' '{print $1}' /etc/passwd)
do
          echo This is $i $user
          #下面两种自增用法,熟悉那种用那种
          #let i++
          i=$[ $i + 1 ]
done

[root@manage for]# sh for14.sh
This is 1 root
This is 2 bin
This is 3 daemon
This is 4 adm
This is 5 lp
This is 6 sync
This is 7 shutdown
This is 8 halt
.......

需求5:批量创建100个用户,比如输入test则会创建test001-100

#怎么输出001-100		seq -w 1 100

[root@manage for]# cat for15.sh 
#!/bin/bash
for user in $(seq -w 1 100)
do
     useradd $1$user &>/dev/null 
     echo $1$user 创建成功
done

[root@manage for]# sh for15.sh  test
test001 创建成功
test002 创建成功
test003 创建成功
test004 创建成功
test005 创建成功
.......


#如果用户创建,则跳过,加判断
[root@manage for]# cat for16.sh 
#!/bin/bash

for user in $(seq -w 1 100)
do
     #判断用户已存在,则输出用户存在,如果不存在,则创建
     id $1$user &>/dev/null
     if [ $? -eq 0 ];then
          echo $1$user用户已经存在
     else
        useradd $1$user &>/dev/null 
        echo $1$user 创建成功
     fi
done

[root@manage for]# useradd aaa5
[root@manage for]# sh for16.sh aaa
aaa1 创建成功
aaa2 创建成功
aaa3 创建成功
aaa4 创建成功
aaa5用户已经存在


#另一种写法
[root@manage for]# cat for17.sh 
#!/bin/bash
for user in $(seq -w 1 10)
do
     id $1$user &>/dev/null
     if [ $? -ne 0 ];then
           useradd $1$user
           echo "$1$user is ok"
     else
           #表示结束当前本次的循环,直接开始下一次循环
           continue
     fi
done

需求6:

批量创建用户脚本,需要用户输入创建的用户数量,以及需要用户输入创建的前缀。例如:前缀qq,个数10,代表创建qq1~qq10,总共10个用户。

[root@manage for]# cat for18.sh 
#!/bin/bash
read -p "请输入你要创建的用户名:" qz
read -p "请输入你要创建的用户数量:" hz
read -p "你要创建的用户前缀是$qz,后缀是$hz,你确定要创建吗 [ y | n ] " Action

case $Action in
      y|Yes|Y)
         for num in $(seq 1 $hz)
         do
              username=$qz$num
              id $username &>/dev/null
              if [ $? -ne 0 ];then
                   useradd $username
                   echo "$username用户创建成功"
              else
                   #表示结束当前本次的循环,直接开始下一次循环
                   continue
              fi
         done
      ;;
      n)
           echo "不创建用户"
           exit 1
      ;;
      *)
         echo "请按照提示输入"
         exit
esac

[root@manage for]# sh for18.sh 
请输入你要创建的用户名:qq
请输入你要创建的用户数量:10
你要创建的用户前缀是qq,后缀是10,你确定要创建吗 [ y | n ] y
qq1用户创建成功
qq2用户创建成功
......

需求7:批量创建用户脚本,需要用户输入创建的用户数量(必须是整数),同时还需要用户输入前缀(前缀不能为空)。

[root@manage for]# cat for19.sh 
#!/bin/bash
read -p "请输入你要创建的用户名:" qz
if [ -z $qz ];then
        echo "请不要输入空值...."
        exit
fi

read -p "请输入你要创建的用户数量:" hz
if [[ ! $hz =~ ^[0-9]+$ ]];then
           echo "请输入数字....."
           exit
fi
read -p "你要创建的用户前缀是$qz,后缀是$hz,你确定要创建吗 [ y | n ] " Action

case $Action in
      y|Yes|Y)
         for num in $(seq 1 $hz)
         do
              username=$qz$num
              id $username &>/dev/null
              if [ $? -ne 0 ];then
                   useradd $username
                   echo "$username用户创建成功"
              else
                   #表示结束当前本次的循环,直接开始下一次循环
                   continue
              fi
         done
      ;;
      n)
           echo "不创建用户"
           exit 1
      ;;
      *)
         echo "请按照提示输入"
         exit
esac


[root@manage for]# sh for19.sh 
请输入你要创建的用户名:
请不要输入空值....
[root@manage for]# sh for19.sh 
请输入你要创建的用户名:aaaa
请输入你要创建的用户数量:
请输入数字.....

需求8:循环批量创建用户,需要填入用户的数量、用户的前缀、用户的统一密码(使用read、case、for语句)

[root@manage for]# cat for20.sh 
#!/bin/bash

read -p "请输入你要创建的用户名:" qz
if [ -z $qz ];then
        echo "请不要输入空值...."
        exit
fi

read -p "请输入你要创建的用户数量:" hz
if [[ ! $hz =~ ^[0-9]+$ ]];then
           echo "请输入数字....."
           exit
fi
read -p "你要创建的用户前缀是$qz,后缀是$hz,你确定要创建吗 [ y | n ] " Action

#输入设置的密码
read -p "给用户设置密码:" pw
case $Action in
      y|Yes|Y)
         for num in $(seq 1 $hz)
         do
              username=$qz$num
              id $username &>/dev/null
              if [ $? -ne 0 ];then
                   useradd $username
                   #直接给创建的用户输入统一密码
                   echo "$pw" | passwd --stdin $username
                   echo "$username用户创建成功,密码是$pw"
              else
                   #表示结束当前本次的循环,直接开始下一次循环
                   continue
              fi
         done
      ;;
      n)
           echo "不创建用户"
           exit 1
      ;;
      *)
         echo "请按照提示输入"
         exit
esac

[root@manage for]# sh for20.sh 
请输入你要创建的用户名:ww
请输入你要创建的用户数量:2
你要创建的用户前缀是ww,后缀是2,你确定要创建吗 [ y | n ] y
给用户设置密码:123456
Changing password for user ww1.
passwd: all authentication tokens updated successfully.
ww1用户创建成功,密码是123456
Changing password for user ww2.
passwd: all authentication tokens updated successfully.
ww2用户创建成功,密码是123456
[root@manage for]# su - ww1
[ww1@manage ~]$ su - ww2
Password: 
[ww2@manage ~]$ su - root
Password: 
Last login: Thu Apr 21 08:07:16 CST 2022 from 10.0.0.1 on pts/1

需求9:通过读入文件中的用户,进行批量添加用户

[root@manage for]# cat user.txt 
aaaa
bbbb
cccc

[root@manage for]# cat for21.sh 
#!/bin/bash
for user in $(cat user.txt)
do
       useradd $user
done

[root@manage for]# sh for21.sh 
[root@manage for]# id aaaa
uid=1319(aaaa) gid=1319(aaaa) groups=1319(aaaa)
[root@manage for]# id bbbb
uid=1320(bbbb) gid=1320(bbbb) groups=1320(bbbb)
[root@manage for]# id cccc
uid=1321(cccc) gid=1321(cccc) groups=1321(cccc)

10.通过读入文件中的用户与密码文件,进行批量添加用户。文件中的格式: user:passwd

[root@manage for]# cat user.txt 
ddaaaa:11111
ddbbbb:111111
ddcccc:22222

[root@manage for]# cat for22.sh 
#!/bin/bash
for user in $(cat user.txt)
do
    us=$(echo $user | awk -F ":" '{print $1}')
    pw=$(echo $user | awk -F ":" '{print $2}')

    id $us &>/dev/null
    if [ $? -eq 0 ];then
         echo "$us 已经存在...."
         continue
         else
            useradd $us &>/dev/null
            echo "$pw" | passwd --stdin $us
    fi
done

[root@manage for]# sh for22.sh 
Changing password for user ddaaaa.
passwd: all authentication tokens updated successfully.
Changing password for user ddbbbb.
passwd: all authentication tokens updated successfully.
Changing password for user ddcccc.
passwd: all authentication tokens updated successfully.


需求11:批量创建用户,用户名oldxu01-100 密码随机(8~12), 然后将创建成功的用户名及密码写入到一个文件中.

#创建随机密码:mkpasswd -l 8  (后面数字是几,就创建几位随机密码)
	
dev:dasd1#!@#!@dsa
dev:dascxasdas1!@#

[root@manage for]# cat for23.sh 
#!/bin/bash
#1.创建10个用户
for user in dev{1..10}
do
    #2.设定随机密码(for循环一次,就生成一次)
    pass=$(mkpasswd -l 8)
   
    #3.创建用户
    useradd $user
    echo "$pass" | passwd --stdin $user &>/dev/null
    
    #4.保存每次的用户名和密码
    #echo "$user:$pass" >> user_pass.txt
    #这两条命令都可以,只不过tee -a既可以输出到屏幕,也可以输出到文件
    echo "$user:$pass" | tee -a user_pass.txt
done

需求12:写一个倒计时脚本,从10计数到0

[root@manage for]# cat for25.sh 
#!/bin/bash
for i in {10..1}
do
     echo -n -e "最后倒计时:$i \r"
     sleep 1
done


需求13:写一个随机点名脚本

[root@manage for]# cat name.txt 
何玲
欧文
欧文
徐冬冬
小强
小鹏
小鹏
扎西德勒
冯绍峰
小明
马蓉
张杰
小红
科比
杨幂
王宝强

[root@manage for]# cat for26.sh 
#!/bin/bash

if [ -s name.txt ];then
#不为空,走这里
         User=$( sort --random-sort name.txt | awk 'NR==1')
         echo $User
   
         grep $User name.txt >>name1.txt
         sed -i '/'$User'/d' name.txt
#如果为空,走下面
else
         cat name1.txt >name.txt
         rm -f name1.txt
    echo "没有名单"       

fi

需求14:下载https://mirrors.aliyun.com/zabbix/zabbix/4.0/rhel/7/x86_64/页面中的所有rpm包至本地


[root@manage for]# cat for27.sh 
#!/bin/bash

curl https://mirrors.aliyun.com/zabbix/zabbix/4.0/rhel/7/x86_64/ &>url.txt

Url_file=url.txt
Pkg_name=$(grep '<a href=' $Url_file |awk -F '"' '{print $4}' | egrep -v 'channel-title|repodata|debuginfo|\.\./|dropmenu-button am-icon-more')
Get_url=https://mirrors.aliyun.com/zabbix/zabbix/4.0/rhel/7/x86_64/

for package in $Pkg_name
do
      #完整的url地址
      url_package=$Get_url$package
    
      #指定下载到某个目录
       [ -d /mnt/rpm ] || mkdir /mnt/rpm
       wget -O /mnt/rpm/$package $url_package &>/dev/null

      if [ $? -eq 0 ];then
            echo "软件包:$pkg is ok...."
       else
            echo "err......."
      fi
done

需求15:使用for循环备份mysql库,每个库对应一个sql文件,需要排除没用的

	#1.拿到需要的库名称:mysql -uroot -pzabbix -e "show databases" | sed 1d |egrep -v '*_schema|mysql|test'
	#2.循环拼接备份命令   mysqldump -uroot -pzabbix  -B zabbix >/mysql/data/zabbix.sql
	
[root@manage for]# cat for-mysql.sh 
#!/bin/bash
db_name=$(mysql -uroot -pzabbix -e "show databases" | sed 1d | egrep -v '*_schema|mysql|test')
Path=/mysql/backup/
Date=$(date +%F)
    [ -d $Path ] || mkdir -p $Path
for i in $db_name
do
       mysqldump -uroot -pzabbix -B ${i} >$Path/${i}_$Date.sql
       #if  [ $? -eq 0 ];then
        if [ -f $Path/${i}_$Date.sql ];then
               echo "$db_name库备份ok......"
          else
               echo "$db_name库备份err....."
       fi
done

      #保留最近15天的备份数据
   find $Path -type d  -mtime +15 |xargs rm -f


需求16:使用for循环进行分库分表备份

	#分库:  值得是多个库分开备份.
	#分表:  一个库中有多个表,将多个分开备份
	
	#备份表
	mysqldump -u<username> -p<password> dbname tablename1 tablename2... > /path/to/***.sql
	mysqldump -uroot -pzabbix  zabbix  users >/mysql/data/zabbix/2022-04-22/users.sql
	
	1.取出所有的库名称
	2.取出库对应的所有表
	3.将命令拼接在一起完成备份

[root@manage for]# cat for-mysql-tables.sh 
#!/bin/bash
db_name=$(mysql -uroot -pzabbix -e "show databases" | sed 1d | egrep -v '*_schema|mysql|test')
Path=/mysql/backup/
Date=$(date +%F)
    #1.判断备份存放目录是否存在,不存在则创建
    [ -d $Path ] || mkdir -p $Path
for i in $db_name
do
    #2.取出对应库的所有表名
    tables=$(mysql -uroot -pzabbix -e "use $i; show tables;" |sed 1d)
    for j in $tables
    do
        #判断对应目录是否存在
        [ -d $Path/$i/$Date/ ] || mkdir -p $Path/$i/$Date/
        #执行备份命令
        mysqldump -uroot -pzabbix $i $j >$Path/$i/$Date/${j}.sql
    done
    
done

      #保留最近15天的备份数据
      find $Path/$i/ -type d -mtime +15 | xargs rm -rf 

需求17:实现主从同步探测脚本

#配置邮箱
yum install mailx -y
vim /etc/mail.rc
set from=Tareya@163.com
set smtp=smtp.163.com
set smtp-auth-user=Tareya@163.com#
set smtp-auth-password=Tareya4454
set smtp-auth=login
set ssl-verify=ignore
set nss-config-dir=/etc/pki/nssdb/

#1.判断IO线程和sql线程是否都为YES,如果是则成功
#2.如果IO线程失败,则直接邮件通知,如果sql线程失败,则检查是什么错误状态码,根据状态码修复
#3.无法修复,或任何错误代码太复杂建议,直接发邮件通知管理员

[root@manage for]# cat mysql_slave.sh 
#!/bin/bash
IO_Status=$(mysql -uroot -pzabbix -e "show slave status\G"| awk '/Slave_IO_Running/ {print $2}')
SQL_Status=$(mysql -uroot -pzabbix -e "show slave status\G"| awk '/Slave_SQL_Running/ {print $2}')

#将结果定义为函数,case中调用函数即可
slave_sql_err_message(){
                       mysql -uroot -pzabbix -e "show slave status\G"|grep "Last_SQL" >/tmp/sql_err.log
                       #发送邮件
                       mail -s "Mysql Master Slave SQL ERROR $(date +%F)" 111222222号@qq.com < /tmp/sql_err.log
                       echo "邮件通知成功"
}

slave_io_err_message(){
                       mysql -uroot -pzabbix -e "show slave status\G"|grep "Last_IO" >/tmp/io_err.log
                       #发送邮件
                       mail -s "Mysql Master Slave IO ERROR $(date +%F)" 111222222号@qq.com < /tmp/io_err.log
                       echo "邮件通知成功"
}



if [ "$IO_Status" == "YES" ] && [ "$SQL_Status" == "YES" ];then
          echo "Mysql 主从正常....."
else
          if [ ! $IO_Status == "YES" ];then
                     slave_io_err_message
                  
          fi
           #2.判断sql异常
          if [ ! $SQL_Status == "YES" ];then
                     SQL_ERR=$(mysql -uroot -pzabbix -e "show slave status\G"|awk '/Last_SQL_Erron/ {print $2}')
 
           #3.精细化判断主从不同步的问题
           case $SQL_ERR in
                 1007)
                     echo "主从的SQL线程出现问题,尝试使用set global sql_slave_skip_counter=1跳过错误"
                     sleep 2
                     mysql -uroot -pzabbix -e "stop slave;set global sql_slave_skip_counter=1;start slave;"
                      SQL_ERR1=$(mysql -uroot -pzabbix -e "show slave status\G"|awk '/Last_SQL_Erron/ {print $2}')
                     if [ $SQL_ERR1 -eq 0 ];then
                           echo "尝试跳过了一次,恢复Mysql数据库成功"
                       else
                           slave_sql_err_message
                     fi
                     ;;
                 1008)
                          slave_sql_err_message
                     ;;
                 1032)
                           slave_sql_err_message
                     ;;          
                 *)
                           slave_sql_err_message
 esac
 
          fi

fi

  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值