Shell编程学习笔记03

第三章、循环

Shell循环:for

语法结构

for 变量名 [ in 取值列表 ]

do

循环体

done

示例

需求:自动循环创建10个用户

for i in (1..10)

do

useradd "user$i"

done\

(for i in $(seq 1 10) 与 for i in `seq 10`也可以)

案例1:ping测试主机

通过循环工具,探测全网主机。将在线主机记录在文本中。

[root@localhost scripts]# cat ip.txt

172.16.8.100

172.16.8.4

172.16.100.254

演示:

思路:

  1. 编写常规ping测试脚本(无循环)
  2. 添加循环语句。for i in (2..254)
  3. 优化脚本(后台执行,清空脚本,循环完成提示,wait间隔)

示例:

1.编写常规网络测试脚本

#!/bin/bash

#ping

ip=192.168.100.10

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

if [ $? -eq 0 ];then

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

fi

2.因为测试对象多,所以使用循环。

#!/bin/bash

#ping

for i in (2..254)

do

ip=192.168.100.$i

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

if [ $? -eq 0 ] ;then

fi

done

3.优化脚本(后台执行,清空脚本,wait间隔)

#!/bin/bash

#ping

>ip.txt ##清空记录文本

for i in (2..254)

do

{

ip=192.168.100.$i

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

if [ $? -eg 0 ];then

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

fi

}& ##后台执行

done

wait ##等待前一个程序执行完毕。在执行下一个命令。

echo "finishing..."

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

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

[root@localhost scripts]# cat user.txt

qianqian

qianfeng

fengfeng

演示:

示例:

#!/bin/bash

for user in `cat user.txt`

do

useradd $user

echo "$user is created"

done

升级

用户可以使用参数的形式,自定义用户名文件。如果用户没有输入用户名文件,提示用户输入如果用户输入的不是文件,提示用户更正。启动循环创建用户。如果用户已经存在,提示存在。 如果用户不存在,则创建成功,提示成功

#!/bin/bash

#name

#time

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

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

前提1:已经完成秘钥登录配置(ssh-keygen)

前提2:定义主机地址列表

前提3:并了解远程修改密码的方法

免密码登录:

ssh-keygen

ssh-copy-ip ip地址

示例:

#邀请用户输入新密码

read -p "请用户输入新密码:”password

#循环调用IP地址

for i in $(cat ip.txt)

do

{

#测试IP是否在线

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

#在线IP进行修改

if [ $? -eq 0 ];then

#修改密码

ssh $i "echo $password I passwd --stdin root"

#修改成功与否并记录

if [ $? -eq 0 ] ;then

echo "$i" >> ok.txt

else

echo $i >> fail.txt

fi

#不在线的主机记录。

else

echo $i >> meigai.txt

fi

}&

done

Shell循环:while until

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

一、while语句结构

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

while 条件测试

do

循环体

done

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

例:

每秒显示 数字,一次递增+1

while:

do

let i++

sleep 1

echo $i

done

二、until语法结构

until语法结构

until 条件测试

do

循环体

done

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

例:

每个秒循环一个数字

#!/bin/bash

until [[ $i -eq 14 ]]

do

let i++

sleep 1

echo $i

done

三、循环总结

循环是编程中常用的控制结构,用于重复执行一段代码块。在Shell脚本中,有两种常见的循环类型:固定循环和不固定循环。

固定循环(for循环): 固定循环使用

for关键字,用于在给定的范围内重复执行一段代码。它通常用于遍历数组、列表或指定的数字范围。

不固定循环: 不固定循环使用

while和until关键字,根据条件的真假来决定是否继续执行循环。它们通常用于在满足特定条件时重复执行代码块。

while和until循环的区别在于条件的判断方式。while循环在条件为真时执行,而until循环在条件为假时执行。

这些循环结构可以根据具体的需求和条件来选择使用。它们提供了灵活的方式来重复执行代码,使得Shell脚本更加强大和可控。

expect

前言

观察ssh登录的交互现象

有些程序难以避免的需要交互,该如何解决脚本与程序的交互问题?

例:

[root@localhost ~]# ssh [email protected]

The authenticity of host '192.168.142.132(192.168.142.132)' can't be established.

ECDSA key fingerprint is SHA256:

MGpJldCNO2i5qW/

7CIZCh5bcUHU0sp5ue5rluN+E/g0.

ECDSA key fingerprint is MD5:ec:36:5d:68:36:0f:91:ae:63:d2:f3:2c:76:81:f2:21.

Are you sure you want to continue

connecting (yes/no)?

名词解释

期待,预期,盼望,预料 料想,指望,希望,要求,想,认为

我们通过Shell可以实现简单的控制流功能如:循环、判断等。但是对于需要交互的场合则必须通过人工来干预,有时候我们可能会需要实现和交互程序如ssh服务器等进行交互的功能。而Expect就使用来实现这种功能的工具。

Expect是一个免费的编程工具语言,用来实现自动和交互式任务进行通信,而无需人的干预。Expect的作者Don Libes在1990年开始编写名词解释 Expect时对Expect做有如下定义:Expect是一个用来实现自动交互功能的软件套件 (Expect [is a] software suite for automating interactive tools)。使用它系统管理员 的可以创建脚本用来实现对命令或程序提供输入,而这些命令和程序是期望从终端(terminal)得到输入,一般来说这些输入都需要手工输入进行的。Expect则可以根据程序的提示模拟标准输入提供给程序需要的输入来实现交互程序执行。甚至可以实现实现简单的BBS聊天机器人。)

解决人机交互的问题

安装

yum install -y expect tcl tclx tcl-devel

示例1:

通过expect解决ssh交互问题

1.通过expect编写脚本

示例:

#!/usr/bin/expect

spawn ssh [email protected]

expect {

"yes/no" { send"yes\r";exp_continue }

"password:" { send "666666\r" };

}

interact

2.登录验证免交互

示例2:

expect实战:公钥推送

准备工作:安装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/nulli

echo "$ip" >> ip.txt

fi

}&

done

cat ip.txt 观察在线主机

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

set timeout 10

spawn ssh-copy-id $ip

expect {

"yes/no" { send "yes\r"; exp_continue }

"password:" { send "centos\r" }

}

expect eof

EOF

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测试主机是否在线。之前插入示例 安装和准备秘钥。

你可能感兴趣的:(学习,笔记,chrome)