目录
一 shell循环:for
结构语法:
ping测试主机:
使用for实现批量主机root密码的修改
二 shell循环:while until
特点
while语句结构
until语句结构
总结
三 expect 语言
名词解释
安装
示例2:公钥推送
四 练习
for
do
循环语句
done
#!/bin/bash
>upip.txt
>downip.txt #优化脚本,每次执行前清空记录文件
for i in `seq 10` #`sep 10`相当于{1..10} 1到10
do #为真。满足条件时,执行循环,
ip=10.8.162.$i #准备1~10ip
ping -c1 -W1 $ip &> /dev/null #ping 1~10 ipif [ $? -eq 0 ] #如果有此ip
then
echo "$ip" >> upip.txtsleep 1 #优化脚本,每ping一次停1秒
else #如没有此ip
echo "$ip" >> downip.txt
fi
done #不满条件退出循环
通过用户列表文件创建用户:
#vim user.txt
useradd user1
useradd user2
useradd user3
#vim useradd.sh
#!/bin/bash
for user in `cat user.txt`
do
useradd $user
echo "$user is created"
done
用户可以使用参数的形式,自定义用户名文件。
如果用户没有输入用户名文件,提示用户输入
如果用户输入的不是文件,提示用户更正。
启动循环创建用户
如果用户已经存在,提示存在
如果用户不存在,则创建成功,提示成功
#!/bin/bash
pass=123
if [ $# -eq 0 ] ;then #判断脚本是否有参数
echo "usage:$0 filename "
exit 1
fi
if [ ! -f $1 ];then #判断用户输入的是否是文件
echo "error filename"
exit 2
fi
for user in `cat $1` #设置循环,读取文件,创建用户
do
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
done
在 ip.txt 文件里输入要管理的主机ip
#vim ip.txt
192.168.56.100
192.168.56.200
192.168.56.300
192.168.56.400
统一修改密码:
#!/bin/bash
>yespass.txt 清空文件夹
>nopass.txtfor i in `cat ip.txt` 打开准备的ip 文件脚本,符合条件进入循环
do 执行循环
ping -c1 -w1 $i &> /dev/null 每秒ping一个ip地址,不要结果if [ $? -eq 0 ] 如果结果为真
then 执行以下命令ssh root@$i "echo 666666 | passwd --stdin root" #登录此ip的root账号,及密码
echo "$i is up" >> yespass.txt
else 结果为假
echo "$i is down" >> nopass.txt
echo "$i 无法修改"
fi #if语句结束
done #不符合条件结束循环体
循环次数不(一定)是固定的
特点:死循环 / 祖行处理文件
语法:
while 条件测试 #当条件测试为真,执行循环体
do
循环体
done 结束语句
例:每秒数一个数
while: # : 冒号是为真的意思
do
let i++ # i 初始值0
sleep 1
echo $i
done
#!/bin/bash
i=0 #定义 i 初始值为0
while [ $i -lt 5 ] #判断当 i <5 为真,执行语句
do
let i++
sleep 1
echo $i
done #判断语句为假时
语法:(与while语义相反)
until 条件语句 #为假时,执行循环语句
do
循环体
done
示例1:
需求:每秒循环一个数字
#!/bin/bash
i=0
until [[ $i -eq 5 ]] //执行语句,直到 i=5 时停止
do
let i++ # i=4 ,会执行语句,i++=5,所以输出结果有 5
sleep 1
echoh $i
done
例二:
每隔5秒查看liuxin用户是否登录,循环往复。
如果该用户登录,请显示登录并退出监控程序;
否则显示当前时间,并输出aofa尚未登录
#!bin/bash
until who |grep liuxin &> /dev/null
do
echo " `date` 用户没有登录"
sleep 2
done
echo “叮当。用户登录了”
exit 1
前言
观察ssh登录的交互现象
有些程序难以避免的需要交互。你该如何解决脚本与程序的交互问题?
编辑回复执行程序时的对话
通过编辑脚本输入你回答的:期待, 预期, 盼望, 预料,料想, 指望, 希望, 要求,想, 认为
1.概述:
我们通过Shell可以实现简单的控制流功能,如:循环、判断等。但是对于需要交互的场合则必须通过人工来干预,有时候我们可能会需要实现和交互程序如telnet服务器等进行交互的功能。而Expect就使用来实现这种功能的工具。
Expect是一个免费的编程工具语言,用来实现自动和交互式任务进行通信,而无需人的干预。Expect的作者Don Libes在1990年开始编写Expect时对Expect做有如下定义:Expect是一个用来实现自动交互功能的软件套件 (Expect [is a] software suite for automating interactive tools)。使用它系统管理员 的可以创建脚本用来实现对命令或程序提供输入,而这些命令和程序是期望从终端(terminal)得到输入,一般来说这些输入都需要手工输入进行的。 Expect则可以根据程序的提示模拟标准输入提供给程序需要的输入来实现交互程序执行。甚至可以实现实现简单的BBS聊天机器人。:)
Expect是不断发展的,随着时间的流逝,其功能越来越强大,已经成为系统管理员的的一个强大助手。Expect需要Tcl编程语言的支持,要在系统上运行Expect必须首先安装Tcl。
2.Expect工作原理
从最简单的层次来说,Expect的工作方式象一个通用化脚本工具。用来实现计算机之间需要建立连接时进行特定的登录会话的自动化。
脚本由一系列expect-send对组成:expect等待输出中输出特定的字符,通常是一个提示符,然后发送特定的响应。
yum install -y expect tcl tclx tcl-devel
示例1
通过expect解决ssh交互问题 (在一台主机上登录另一台主机 )
#!/bin/expect
spawn ssh [email protected]
expec {
"yes/no" { send "yes/r" ; exp_contijnue }
"password:" { send"666666/r" };
}
interact
准备工作:安装expect,准备公钥
1. 准备shell循环判断在线主机
#!/bin/bash
#创建一个IP地址文件。
>ip.txt
#使用for循环ping测试主机是否在线。
for i in {2..254}
do
{
#注意环境的IP地址,可能与示例中不同。
ip=192.168.0.$i
ping -c1 -W1 $ip &> /dev/null
if [ $? -eq 0 ];then
echo "$ip" >> ip.txt
fi
}&
done
2.通过expect进行交互
#!/bin/bash
#创建一个IP地址文件。
>ip.txt
#使用for循环ping测试主机是否在线。
for i in {2..254}
do
{
#注意练习环境的IP地址,可能与示例中不同。
ip=192.168.122.$i
ping -c1 -W1 $ip &> /dev/null
if [ $? -eq 0 ];then
echo "$ip" >> ip.txt/usr/bin/expect <<-EOF
set timeout 10
spawn ssh-copy-id $ip
expect {
"yes/no" { send "yes\r"; exp_continue }
"password:" { send "centos\r" }
}
expect eof
EOF
fi
}&
done
wait
echo "finishi..."
#!/usr/bin/expect
set timeout 10
spawn ssh-copy-id 192.168.122.152
expect {
"yes/no" { send "yes\r"; exp_continue }
"password:" { send "centos\r" }
}
3.优化脚本
安装和公钥
#!/bin/bash
#创建一个IP地址文件。
>ip.txt
#检测expect是否安装,检测公钥是否创建。
rpm -q expect &> /dev/null
if [ $? -ne 0 ] ;then
yum install -y expect
fi
if [ ! -f ~/.ssh/id_rsa ];then
ssh-keygen -P "" -f ~/.ssh/id_rsa
fi
#使用for循环ping测试主机是否在线。之前插入安装和准备秘钥。
学员虚拟机环境重置
case判断成绩
#!/bin/bash
read -p "请输入你考试的分数:" score
case "$score" in
[0-9])
echo "您没有及格,请下次努力!"
;;
[1-5][0-9])
echo "您没有及格,请下次努力!"
;;
[6-7][0-9])
echo "您的成绩及格,请更加努力!"
;;
[8-9][0-9])
echo "您的成绩为优秀,请再接再厉!"
;;
100)
echo "您的成绩为优秀,请再接再厉!"
;;
*)
echo "您输入的成绩超出合理值,请重新输入!"
;;
esac
双网关自动切换
#!/bin/bash
gw1=192.168.10.253
gw2=192.168.10.251
(
while : //条件恒真,进入死循环
do
route del default
route add default gw $gw1 //删除默认网关,并设gw1为默认网关。这两个命令主要是为了第二个循环结束后进行的操作
while ping -c 1 $gw1 &> /dev/null //测试能否ping通主网关。while循环是测试条件成立会继续循环,即继续ping下去
do
sleep 1 //ping成功会休眠一秒
done //ping不通结束循环
route del default
route add default gw $gw2 //第一个循环结束后进行的操作,删除默认网关,并将gw2设为默认网关
until ping -c 1 $gw1 &> /dev/null //进入第二个循环继续ping主网关。until循环是测试条件不成立会继续循环,即ping不通继续ping
do
sleep 1
done //ping通了就结束循环,又重新进入死循环进行的操作。就是删除默认网关,并gw1为默认网关
done
) & //将脚本里的命令加入后台执行