shell脚本第四阶段----随机数与循环嵌套

一、随机数

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


产生0~1之间的随机数
echo $[$RANDOM%2]

产生0~2之间的随机数
echo $[$RANDOM%3]

产生0~3之间的随机数
echo $[$RANDOM%4

50~100
echo $[$RANDOM%51+50]

1.实战案例

1.1写一份脚本,产生一个phonenum.txt文件,随机产生以139开头的手机号1000个,每个一行

分析:

1.产生1000个电话号,需要循环1000次

2.139+8位,后8位随机产生,可以让每一位数字都随机产生,\[RANDOM%10]

3.将随机产生的数字分别保存到变量里,然后加上139保存到文件里。

bash 复制代码
#! /bin/bash
for i in {1..1000}
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]
 echo "139$n1$n2$n3$n4$n5$n6$n7$n8" >> phonenum.txt
done

二、嵌套循环

一个循环体内又包含另一个完整的循环结构,称为循环的嵌套。在外部的循环的每次执行过程中都会触发内部循环,直至内部完成一次循环,才接着执行下一次的外部循环。for循环、while循环和until循环可以互相嵌套

demo1:打印如下图案

bash 复制代码
1
12
123
1234
12345

分析:
1、使用循环语句能够打印出12345
2、外部循环只打印行,内部循环打印12345数字

#!/bin/bash
for ((i=1;i<=5;i++))
do
  for ((j=1;j<=$i;j++))
   do
   echo -n $j
   done
echo
done

三、expect程序交互

expect自动应答 tcl语言

需求1:server远程登陆到node2上什么都不做

bash 复制代码
#开启一个程序
spawn ssh root@10.1.1.1
expect {
         "(yes/no)?" { send "yes\r";exp_continue }
         "password:" { send "123456\t" }
}
interact

需求2:登陆后需要操作一些事情

bash 复制代码
#开启一个程序
spawn ssh root@10.1.1.1
expect {
         "(yes/no)?" { send "yes\r";exp_continue }
         "password:" { send "123456\t" }
}
#interact
expect "#"
#捕获到#号开始发送下面的命令
send "hostname\r"
send "useradd stu01\r"
send "pwd\r"
send "exit\r"
#结束退出
expect eof

需求3:和shell脚本结合使用

bash 复制代码
cat ip.txt
10.1.1.2 111111
10.1.1.3 123


#! /bin/bash
# 循环在指定的服务器上创建用户和文件
while read ip pass
do
    /usr/bin/expect <<-END &>/dev/null
    spawn ssh root@$ip
    expect {
    "yes/no" { send "yes\r";exp_continue }
    "password:" { send "$pass\r" }
    }
    expect "#" { send "useradd yy1;rm -rf /tmp/*;exit\r" }
    expect eof
    END
done < ip.txt

四、综合案例

写一个脚本,将跳板机上yunwei用户的公钥推送到局域网内可以ping通的所有机器上。说明:主机和密码文件已经提供

10.1.1.1:123456

10.1.1.2:123456

案例分析

关闭防火墙和selinux

判断ssh服务是否开启

循环判断给定密码文件里的哪些ip可以ping通 IP pass

判断ip是否可以ping通-->$?-->流程控制语句

密码文件里获取主机的的ip和密码保存变量 ip pass

判断公钥是否存在--->不存在创建它

ssh-copy-id 将跳板机市的yunwei用户的公钥推送到远程主机-->expect解决交互、

将ping通的主机ip单独保存到一个文件

测试验证

代码拆分

bash 复制代码
1.获取ip并且判断是否可以ping通
1)主机密码文件ip.txt
10.1.1.1:123456
10.1.1.2:123456

2)循环判断主机是否可以ping通
tr ':' ' ' < ip.txt|while read ip pass
do
  ping -c1 $ip &>/dev/null
  if  [$? -eq 0 ];then 
   #判断公钥是否存在
   
   #推送公钥 
     
  fi
done

2.判断yunwei1用户的公钥是否存在
[ ! -f /home/yunwei/.ssh/id_rsa ] && ssh-keygen -P '' -f ./id_rsa

3.非交互式推送公钥
/usr/bin/expect <<-END &>/dev/null
    spawn ssh-copy-id root@$ip
    expect {
        "yes/no" { send "yes\r";exp_continue }
        "password:" { send "$pass\r" }     
    }
    expect eof
END




组装:
tr ':' ' ' < ip.txt|while read ip pass
do
  ping -c1 $ip &>/dev/null
  if  [$? -eq 0 ];then 
   #判断公钥是否存在
   [ ! -f /home/yunwei/.ssh/id_rsa ] && ssh-keygen -P '' -f ./id_rsa
   #推送公钥 
   /usr/bin/expect <<-END &>/dev/null
    spawn ssh-copy-id root@$ip
    expect {
        "yes/no" { send "yes\r";exp_continue }
        "password:" { send "$pass\r" }     
    }
    expect eof
  END  
  fi
done