• Shell-06循环结构


    说起循环不得不谈的就是数组,一般我们也不会操作字符串进行循环,虽然偶尔会这样。

    数组

    变量

    name=kai #变量
    ———————
    |k|a|i|
    ———————
    |0|1|2|
    ———————
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    普通数组

    books=(liunx python awk docker) #普通数组
    --------------------------
    |liunx|pythona|awk|docker|
    --------------------------
    |0    |1      |2  |3     |
    --------------------------
    
    引用
    #普通数组
    ${books[3]}
    docker
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    索引数组

    info=([name]=kaikai.wang [liunx]=centos [age]=36) #索引
    --------------------------
    |kaikai.wang|centos|36 |
    --------------------------
    |name       |liunx |age|
    --------------------------
    
    引用
    #索引
    ${info[liunx]}
    docker
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    访问数组

    echo ${array1[0]} 访问数组中的第一个元数
    echo ${array1[@]} 访问数组中所有元数 等同于 echo $(arrary1[*])
    echo ${#array1[@]} 统计数组元数的个数
    echo ${!array1[@]}  显示所有的索引
    echo ${#array1[@]:1} 从数组下标1开始
    echo ${#array1[@]:1:2} 从数组下标1开始,访问2个元素
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    for

    for循环是按照空格划分其中的值,空行不需要进行判断

    for语法结构

    for 变量名 [in 取值列表]
    do 
    	循环体
    done
    
    • 1
    • 2
    • 3
    • 4

    ping 多台主机

    #!/usr/bin/bash
    #ping主机检测
    
    # >ip.txt  重定向
    
    #for i in {2..254}
    #
    for i in  `seq 2 254`
    do
    	{
        ip = 192.168.110.$i
        ping -c1 -W1 $ip &>/dev/null
        if [ $? -eq 0 ];then
            echo "$ip" | tee -a ip.txt
        fi
        }&    #{}&放在后台
    done
    wait  #等待前面的所有后台程序结束
    echo 'finishi...'   #脚本可以在前面加上time对脚本进行及时
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    ping 指定文件中间的主机

    #!/usr/bin/bash
    for i in `cat ip.txt`
    do
    	ping -c1 -W1 $ip &>/dev/null
    	if [$? -eq 0];then
    		echo "$ip is up"
    	else
    		echo "$ip is down."
    		
    done
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    批量用户添加(文件版本)

    #!/usr/bin/bash
    #判断脚本是否有参数
    if [ $# -eq 0 ];then
    	echo "usage:`basename $0`file"
    	exit 1
    fi
    #判断是否是文件
    if [ ! -f $1 ];then
    	echo "error file
    	exit 2
    fi
    #希望for处理文件按照回车分割,而不是tab或者空格
    #重新定义分隔符
    #IFS内部字段分隔符
    #IFS=$'\n'
    IFS=$'
    '
    
    for line in `cat $1`
    do	
    	user=`echo"$line" | awk '{print $1}'`
    	pass=`echo"$line" | awk '{print $2}'`
    	id $user &>/dev/null
    	if [ $? -eq 0 ];then
    		echo "user $user already exists"
    	else
    		useradd $user
    		echo "$pass" | pass --stdin $user &>dev/null
    		if [$? -eq 0];then
    			echo "$useris is created."
    		fi
    	fi
    
    done
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    for批量修改密码

    #!/bin/bash
    
    read -p "Please enter a New Password:" pass
    
    for ip in $(cat ip.txt)
    do
    	{
    		ping -c1 -W1 $ip &>/dev/null
    		if [ $? -eq 0 ];then
    			ssh $ip "echo $pass | passwd --stdin root"
    			if [ $? -eq 0 ];then
    				echo "$ip" >>ok_`data +%F`.txt
    			else
    				echo "$ip" >> fail_`data +%F`.txt
    			fi
    		else
    			echo "$ip" >> fail_`data +%F`.txt
    		fi
    	}&
    done
    wait
    echo "finish..."
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    for实现ssh配置

    for ip in `cat ip.txx`
    do
    	{
    		ping -c1 -W1 $ip &>/dev/null
    		if [ $? -eq 0 ];then
    			ssh $ip "sed -ri '/^#UseDNS/c\UseDNS no' /etc/ssh/ssd_config"
    			ssh $ip "sed -ri '/^#GSSAPIAuthentication/c\GSSAPIAuthentication no' /etc/ssh/ssd_config"
    		else
    			echo "$ip" >> fail_`data +%F`.txt
    		fi
    	}&
    done
    wait
    echo"all ok..."
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    while

    while的语法结构

    while 判断条件
    do
    	语句结构
    done
    
    
    ==当条件测试成立执行循环体
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    批量生成用户

    #!/bin/bash
    while read line
    do
    	#检测有没有空行,while是需要判断空行的
    	if {${#line} -eq 0};then
    		echo "------"
    		continue
    	fi
    	user=`echo $line|awk '{print $1}'`
    	pass=`echo $line|awk '{print $2}'`
    	id $user &>/dev/null
    	if [ $? -eq 0 ];then
    		echo "user $user already exists"
    	else
    		useradd $user
    		echo "$pass" | passwd --stdin $user &>/dev/null
    		if [ $? -eq 0 ];then
    			echo "$user is created"
    		fi
    	fi
    doen < ip.txt
    wait
    echo "all ok"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    until

    测试远程主机连接

    while的语法结构
    do
    	语句结构
    done
    ==当条件测试不成立的时候执行循环体
    #!/bin/bash
    #在down的时候进行测试,好的就停止
    ip = x.x.x.x
    until ping -c1 -W1 $ip &>/dev/null
    do
    	sleep 1
    done
    echo "$ip is up."
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    for&while

    while实现ping循环

    #!/usr/bin/bash
    > ip.txt
    i=2
    while [$i -le 254]
    do
    	{
        ip = 192.168.110.$i
        ping -c1 -W1 $ip &>/dev/null
        if [ $? -eq 0 ];then
            echo "$ip" | tee -a ip.txt
        fi
        }&    #{}&放在后台
        let i++
    done
    wait  #等待前面的所有后台程序结束
    echo 'finishi...'   #脚本可以在前面加上time对脚本进行及时
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    until实现ping循环

    #!/usr/bin/bash
    > ip.txt
    i=2
    while [$i -gt 254]
    do
    	{
        ip = 192.168.110.$i
        ping -c1 -W1 $ip &>/dev/null
        if [ $? -eq 0 ];then
            echo "$ip" | tee -a ip.txt
        fi
        }&    #{}&放在后台
        let i++
    done
    wait  #等待前面的所有后台程序结束
    echo 'finishi...'   #脚本可以在前面加上time对脚本进行及时
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    fd和并发控制

    可能存在并发数量太大导致无法运行,这样可以使用管道的方式限制后台运行的数量,格式

    #!/bin/bash
    #多并发的脚本
    thread=5#伪进程
    tmp_fifofile=/tmp/$$.fifo #创建管道
    
    mkfifo $tmp_fifofile #创建文件
    exec 8<> $tmp_fifofile  #打开文件
    rm $tmp_fifofile  #删除文件
    
    for i in `seq $thread`
    do 
    	echo >&8   #操作文件符8
    done
    
    for i in {1..254}
    do
    	read -u 8
    	{
    	ip=192.168.110.$i
    	ping -c1 -W1 $ip &>/dev/null
        if [ $? -eq 0 ];then
            echo "$ip is ok"
        else
        	echo "$ip is down"
        fi
        echo >&8 
    	}&
    done
    wait
    exec 8>&_
    echo "all finish..."
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    示例

    array应用

    #!/usr/bin/bash
    #while array
    while read line
    do
    	hosts[++i]=$line
    done </etc/hosts
    
    echo "hosts first:${hosts[1]}"
    echo
    
    for i in ${!host[@]}
    do
    	echo "$i: ${hosts[i]}"
    done
    
    #!/usr/bin/bash
    #for array
    OLD_IFS=$IFS
    IFS=$'\n'
    for line in `cat /etc/hosts`
    do
    	hosts[++i]=$line
    done
    
    for i in ${!host[@]}
    do
    	echo "$i: ${hosts[i]}"
    done
    
    IFS=$OLD_IFS
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    实现性别识别

    #!/bai/bash
    #count sex
    declare -A sex #声明数组变量
    
    while read line
    do
    	type = `echo $line |awk '{print $2}'`
    	let sex[$type]++
    done < sex.txt
    
    for i in ${!sex[@]}
    do
    	echo "$i:${sex[$i]"
    done
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    统计不同类型shell的数量

    把要统计的对象作为数组的索引 sex[m]++ sex[f]++

    #!/bai/bash
    #count shells
    declare -A shells
    
    while read line
    do
    	type = `echo $line |awk -F ":" '{print $NF}'`
    	let shells[$type]++
    	
    done < /etc/passwd
    
    for i in ${!shells[@]}
    do
    	echo "$i:${shells[$i]"
    done
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    统计tcp连接状态数量

    ss -an | grep 80
    
    #!/usr/bin/bash
    unset status
    declare -A status
    type=`ss -an | grep:80 | awk '{print $2}'`
    
    for i in $type
    do
    	let status[$i]++
    done
    
    for j in ${!status[@]}
    do
    	echo "$j : ${status[$j]}"
    done
    
    使用 watch -n2 ./tcp.sh  进行测试
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    批量用户添加

    #!/usr/bin/bash
    while true:
    do
        read -p "Please enter preffix & password & num[tianyun 123 5]:" prefix pass num
        print "user infomation:
        -------------------
        user prefix: $prefix
        user password: $pass
        user number: $num
        ---------------------
        "
        read -p "Are you sure?[y/n]:" action
        if [ "$action" != "y" ];then
            break
        fi
    done
    
    for i in `seq -w $num`
    do
    	user=$prefix$i
    	id $user &>/dev/null
    	if [ $? -eq 0 ];then
    		echo "user $user already exists"
    	else
    		useradd $user
    		echo "$pass" | pass --stdin $user &>dev/null
    		if [$? -eq 0];then
    			echo "$useris created."
    		fi
    	fi
    
    done
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
  • 相关阅读:
    直播课堂系统07-讲师管理模块前端
    <Java编程工具JDK、IDEA安装及环境配置教程>——《Java》
    是时候丢掉BeanUtils了
    50etf期权的隐含波动率是什么意思?最通俗易懂的解释!
    1143. 最长公共子序列
    我的AI音乐梦:ChatGPT帮我做专辑
    从 Oracle 迁移到 TiDB 的方案设计与用户实践
    【最全最详细数据库优化】sql优化的15个小技巧
    七、SSM 框架整合
    记录一次数据库CPU被打满的排查过程
  • 原文地址:https://blog.csdn.net/a13554371686/article/details/126879383