• shell——随机数(RANDOM)+ expect 自动应答



    RANDOM

    bash默认有一个$RANDOM的变量 默认是0~32767。使用set |grep RANDOM 查看上一次产生的随机数

    产生0~1之间的随机数
    echo $[$RANDOM%2]
    
    产生0~2之间的随机数
    echo $[$RANDOM%3]
    
    产生0~3之间的随机数
    echo $[$RANDOM%4]
    。。。。
    产生0~9内的随机数
    echo $[$RANDOM%10]
    
    产生0~100内的随机数
    echo $[$RANDOM%101]
    
    
    产生50-100之内的随机数
    echo $[$RANDOM%51+50]
    
    产生三位数的随机数
    echo $[$RANDOM%900+100]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    示例

    示例1

    写一个脚本,产生一个phonenum.txt文件,随机产生以138开头的手机号1000个,每个一行
    思路:

    1. 循环1000次产生号码
    2. 138+8位数字,后面8位数字随机产生($[RANDOM%10])
    3. 将随机数保存到变量里,在保存到文件里
    #!/bin/bash
    for (( i = 0; i < 1000; i++ ))
    do
            n1=$[RANDOM%10]
            n2=$[RANDOM%10]
            n3=$[RANDOM%10]
            n4=$[RANDOM%10]
            n5=$[RANDOM%10]
            n6=$[RANDOM%10]
            n7=$[RANDOM%10]
            n8=$[RANDOM%10]
            tmp=138$n1$n2$n3$n4$n5$n6$n7$n8
            echo $tmp >> phonenum.txt
    done
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    示例2

    在上面的1000个手机号里抽奖5个幸运观众,显示出这5个幸运观众。但只显示头3个数和尾号的4个数,中间的都用*代替

    
    #!/bin/bash
    #从 phonenum.txt中 随机抽4个号码
    path=/root/test/phonenum.txt
    for (( i = 0; i < 4; i++ ))
    do
            #统计文件的行数
            line=`wc -l $path | cut -d' ' -f1`
            #随机生成行号
            line=$[RANDOM%line+1]
            #定位到指定行的号码
            num=`head -$line $path | tail -1`
            #打印到屏幕
            echo "139****${num:7:4}"
            #把完整号码保存到指定问文件
            echo $num >> winning_numbers.txt
            #删除已经抽过的号码
            sed -i "/$num/d" $path
    done
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    expect 自动应答

    expect是一个用来处理交互的命令。借助Expect,我们可以将交互过程写在一个脚本上,使之自动化完成。
    expect (自动应答),基于tcl语言
    安装 expect yum install expect -y

    在脚本文件的第一行写上这么一行,告诉系统用expect来执行

    #!/usr/bin/expect
    
    • 1

    使用expecrt时基本上就是配合下面4条命令使用

    命令作用
    send用于向进程发送字符串
    expect用于从进程读取字符串
    spawn启动新的进程
    interact运行用户交互

    使用示例

    示例1:A远程登录到另外一台主机上什么都不做

    #!/usr/bin/expect
    #开启一个新的进程
    spawn ssh root@192.168.44.122
    # 捕获相关内容
    expect {
            "(yes/no)?" { send "yes\r";exp_continue }
            "password:" { send "root\r" }
    }
    interact #交互执行
    
    1)定义变量
    #!/usr/bin/expect
    set ip 192.168.44.122
    set passwd root
    spawn ssh root@$ip
    expect {
            "yes/no" { send "yes\r";exp_continue }
            "password:" { send "$passwd\r" }
    }
    interact
    
    2)使用位置参数
    #!/usr/bin/expect
    set ip [ lindex $argv 0 ]
    set passwd [ lindex $argv 1 ]
    spawn ssh root@$ip
    expect {
            "yes/no" { send "yes\r";exp_continue }
            "password:" { send "$passwd\r" }
    }
    interact
    
    #运行脚本时给定参数
    # ./expect.sh 192.168.44.122 root
    
    
    • 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
    • 35
    • exp_continue:无论是捕捉到都继续执行
    • \r:换行

    示例2:A远程登录到另外一台主机上操作

    #!/usr/bin/expect
    set ip 192.168.44.122
    set passwd root
    spawn ssh root@$ip
    expect {
            "yes/no" { send "yes\r";exp_continue }
            "password:" { send "$passwd\r" }
    }
    #只要读取到"#"就会执行下面的代码(root用户是带#的)
    expect "#"
    send "mkdir tmp\r"
    send "cd tmp\r"
    send "touch file{1..5}\r"
    send "exit\r"
    expect eof
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    示例3:shell脚本和expect结合使用,在多台服务器上创建1个用户

    #!/bin/bash
    while read ip passwd
    do
    		#加 - 表示下面的END可以加个制表符号
            /usr/bin/expect <<-END &>/dev/null
            spawn ssh root@$ip
            expect {
            "yes/no" { send "yes\r";exp_continue }
            "password:" { send "$passwd\r" }
            }
            expect "#" { send "useradd my_user;rm -rf /tmp/*;exit\r" }
            expect eof
            END
    done < ip.txt
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    示例4:写一个脚本,将跳板机上test用户的公钥推送到局域网内可以ping通的所有机器上

    准备3台机器

    ip身份
    192.168.44.122内网主机
    192.168.44.166内网主机
    192.168.44.144跳板机

    给跳板机上test用户提权,命令visudo

    ## Allow root to run any commands anywhere
    root    ALL=(ALL)       ALL
    test    ALL=(root)      NOPASSWD:ALL,!/sbin/shutdown,!/sbin/init,!/bin/rm -rf /
    
    • 1
    • 2
    • 3

    在跳板机上创建一个主机密码文件pass.txt
    主机Ip:密码

    192.168.44.122:root
    192.168.44.144:root
    
    • 1
    • 2

    在根目录创建ip_up.txt文件,保存可以ping通的主机ip
    脚本实现

    #!/bin/bash
    #判断公钥是否存在
    [ ! -f /home/test/.ssh/id_rsa ] && ssh-keygen -P '' -f ~/.ssh/id_rsa
    
    #循环判断主机是否ping通,如果ping通推送公钥
    tr ':' ' ' < /test/ip.txt|while read ip password
    do
    {
            ping -c1 $ip &>/dev/null
            if [ $? -eq 0 ];then
            echo $ip >> ~/ip_up.txt
            /usr/bin/expect <<-END &>/dev/null
            spawn ssh-copy-id root@ip
            expecct {
                    "yes/no" { send "yes\r";exp_continue }
                    "password:" { send $password\r" }
            }
            expect eof
            END
            fi
    }&
    done
    wait
    echo "公钥推送完毕,正在测试..."
    #测试验证
    remote_ip=`tail -1 ~/ip_up.txt`
    ssh root@remote_ip hostname &>/dev/null
    test $? -eq 0 && echo "公钥推送成功"
    
    
    • 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

    示例5:写一个脚本,统计web服务的不同连接状态个数

    #!/bin/bash
    
    #统计每个状态的个数
    declare -A array
    states=`ss -ant | grep 80 | cut -d ' ' -f1`
    for i in $states
    do
            let array[$i]++
    done
    #通过遍历数组里的索引和元素打印出来
    for j in ${!array[*]}
    do
            echo $j:${array[$j]}
    done
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
  • 相关阅读:
    男士内裤买什么材质的好?2024男士内裤实测推荐
    六自由度电动并联机器人结构设计(说明书+任务书+cad图纸+proe三维图)
    网络安全在2024好入行吗?
    C语言 基础开发----目录
    GPTZero:论文打假神器
    【C++】三大特性之继承
    C和指针 第13章 高级指针话题 13.5 字符串常量
    Docker安装详细步骤及相关环境安装配置(mysql、jdk、redis、自己的私有仓库Gitlab 、C和C++环境以及Nginx服务代理)
    Hackathon 代码黑客马拉松采访复盘
    使用 Prometheus 监控 eKuiper 规则运行状态
  • 原文地址:https://blog.csdn.net/weixin_53946852/article/details/126430328