Liunx shell编程及自动化运维实现--第三章循环

一、Shell循环:for

语法结构

for  变量名  [in 取值列表]

do

循环体

done

#!/bin/bash     创建十个用户
#for i in {1..10}
#for i in $(seq 1 10)        seq 从一到十输出

for i in  `seq 1 10`           反引号优先执行,跟$()作用一样
do
useradd  "user$i"
done

如果是公司员工姓名

name.txt

zhangsan

lisi

wangwu

for i in  `cat name.txt`           反引号优先执行,跟$()作用一样
do
useradd  "user$i"
done

1.案例1:ping测试主机

for   ip  in   {1..300}

do

ip=192.168.64.$ip

ping -c1 -W1  $ip  &>  /dev/null

if [ $? -eq 0]

then

echo "$ip"  |  tee  -a   ip.txt

fi

done 

优化脚本

>ip.txt                         输入重定向,避免重复输入

for   ip  in   {1..300}

do

{

ip=192.168.64.$ip

ping -c1 -W1  $ip  &>  /dev/null

if [ $? -eq 0]

then

echo "$ip"  |  tee  -a   ip.txt

fi

}&    ##后台执行

wait        等待前一个程序执行完毕,再去执行下一个命令

echo  “finishing。。。”

done 

2.案例2:通过用户列表文件创建用户

通过用户列表文件创建用户

cat  user.txt

zhangsan

lisi

wangwu

#!/bin/bash

for  user  in  `cat  user.txt`

do

useradd  $user

echo  "$user  is  created"

done

升级

用户可以使用参数的形式,自定义用户名文件

#!/bin/bash

for  user  in  `cat  $1`

do

useradd  $user

echo  "$user  is  created"

done

如果用户没有输入用户名文件,提示用户输入

!/bin/bash
if [ $#  -eq  0   ]
then
echo "请在执行程序后,通过第一参数传递文件名"
echo "例如 $0 user.txt"
exit                ## 不能带数字  ,如果带数字会赋值给$?,可赋值给
fi
for user in `cat $1`
        do
                useradd  "user$user"
        echo "user created"
done

如果用户输入的不是文件,提示用户更正

#!/bin/bash
if [ $#  -eq  0   ]
then
echo "请在执行程序后,通过第一参数传递文件名"
echo "例如 $0 user.txt"
exit
fi

if [ !  -f $1 ]                        ##-f 如果参数为文件时返回真   !取反
then
        echo "传递的参数不是文件"
        exit 88
fi

for user in `cat $1`
        do
                useradd  "user$user"
        echo "user 已创建"
done

启动循环创建用户

如果用户已经存在,提示存在

如果用户已经不存在,则创建成功,提示成功

#!/bin/bash
if [ $#  -eq  0   ]
then
echo "请在执行程序后,通过第一参数传递文件名"
echo "例如 $0 user.txt"
exit
fi

if [ !  -f $1 ]
then
        echo "传递的参数不是文件"
        exit 88
fi

for user in `cat $1`
        do
                if id $user &> /dev/null
                then echo "user 存在"
                else
                useradd $user
                echo "user 已创建"
                fi
done

diff         11.sh   22.sh         找出文件的不同

3.案例3:使用for实现批量主机root密码的修改

前提:

        1.已经完成密钥登录配置(ssh-keygen)

        2.定义主机地址列表 

        3.并了解远程修改密码的方法

ssh-keygen          设置密钥        回车

ssh-copy-id   192.168.142.150

ssh  [email protected]  "touch /root/xulei.txt"

ssh  [email protected]  "echo $pass |passwd  --stdin root        改密码

#!/bin/bash
read -p "Please enter a New Passwd:" pass

for ip in `cat ip.txt`
do
{
        ping -c1 -W1 $ip &>/dev/null
        if [ $? -eq 0  ]
        then
                ssh $ip "echo $pass |pass  --stdin root"
                if [ $? -eq 0 ];then
                        echo "$ip" >> ok_`date +%F`.txt
                else
                        echo "$ip" >>fail_`date +%F`.txt
                fi
        else
                echo "$ip" >>fail_`date+%F`.txt
        fi
}&
done
wait
echo "finish.."

注意:for和参数不要离太远,done后面需要再加一行空白

二、Shell循环: while until

特点:循环次数不一定是固定的

1.while语句结构(死循环/逐行处理文件)

while  条件测试        :代表为真

do

循环体

done

当条件测试成立(条件为真),执行循环体

实例:每秒显示一个数字,一次递增+1

#!/bin/bash
while :
do
let i++
echo $i
done

退出程序三个命令

1.exit        退出整个程序

2.break        退出当前循环

3.continue        退出本次循环,进行下一次循环

2.until语法结构

until  条件测试        :代表为真

do

循环体

done

当条件测试成立(条件为假时成立),执行循环体

实例:每秒显示一个数字,一次递增+1

#!/bin/bash
until [[      $i  -eq   14   ]]
do
let i++
echo $i
done

3.循环总结

固定:for

不固定:while until

三、expect

1.前言

        观察ssh登录的交互现象,有点程序难以避免的需要交互,你该如何解决脚本和程序的交互问题?

2.名词解释

        Expect是一个免费的编程语言,用来实现自动和交互式任务进行通信,而无需人的干预。Expect是一个用来实现自动交互的软件套件。使用它系统管理员可以创建脚本来实现对命令或程序提供输入,而这些命令和程序是期望从终端得到输入,一般来说这些输入都需要手工输入进行的,Expect则可以根据程序的提示模拟标准输入提供给程序需要的输入来实现交互程序执行,甚至可以实现简单的BBS聊天机器人

        解决人机交互问题。

3.安装

yum  install  -y  expect  tcl  tclx tcl-devel

4.实例1:通过expect解决ssh交互问题

4.1通过expect编写脚本

#!/usr/bin/expect
spawn ssh [email protected]
expect {
        "yes/no" { send "yes\r",exp_continue }
        "password:" { send "root\r" };
}
interact

4.2登录验证免交互

  • spawn  expect  内部命令,启动一个shell程序
  • expect  期望哪些内容
  • yes/no      就send发送yes,\r表示回车
  • password    就send发送centos
  • exp_continue,跳过循环,就继续下一条语句
  • interact  允许用户交互

如果想实现磁盘自动化,在spawn后加disk

5.实例2:expect实战,公钥推送

注备工作:安装expect,准备公钥

1.通过shell循环判断在线主机

#!/bin/bash
>ip.txt                        输入重定向,避免重复输入
for i in {2..254}
do
{
    ip=192.168.64.$i
    ping -c1 -W1 $ip &> /dev/null
    if [ $? -eq  0  ]
        then echo $ip >>ip.txt
    fi 
}&                          ##后台执行
done 

2.通过expect进行交互

#!/bin/bash
>ip.txt
for i in {2..254}
do
{
    ip=192.168.64.$i
    ping -c1 -W1 $ip &> /dev/null
    if [ $? -eq  0  ]
        then echo $ip >>ip.txt
        #/usr/bin/expect  exp2.exp 
        /usr/bin/expect  <<-EOF 
                set timeout 10   ##超时,时间超过10秒就结束
                spawn ssh-copy-id $ip 
                expect { 
                        "yes/no" { send "yes\r";exp_continue } 
                        "password:" { send "root\r" };
                }
                expect eof
        EOF
        fi
}&
done
wait echo "finishing"

注意:

        1.bash里是无法直接执行expect的,

        2.运行expect用输入重定向,或者把它的内容单独写在文件里,让expect自己去调用

3.优化脚本

!/bin/bash

#创建一个ip文件
>ip.txt

#检测expect是否安装,检测公钥是否创建
rpm -q expect &> /dev/null
if [ $? -nq 0   ]
        then yum install -y expect
fi
if [  ! -f ~/.ssh/id_rsa   ]                                        #有id_rsa是看是否密钥文件
        then ssh-keygen -P "" -f ~/.ssh/id_rsa
fi
#使用for循环ping测试主机手否在线,之前插入安装和准备密钥

四、课后作业

1.使用case实现成绩优良差的判断

2.for创建20用户

用户前缀由用户输入

用户初始密码由用户输入

例如:test01,test10

3.for ping测试指网段的主机

网段由用户输入,例如用户输入192.168.2 ,则ping 192.168.2.10--- 192.168.2.20

UP: /tmp/host up.txt

Down:/tmp/host_down.txt

4.使用for实现批量主机root密码的修改

成功或失败都必须记录

提示:主机IP存放在一个文件中

SSH:实现公钥认证,执行远程中主机命令

实现公钥认证

#ssh-keygen在用于管理的主上生成密钥对

# ssh-copy-id-i192.168.2.3

你可能感兴趣的:(自动化,运维)