【Shell专项】循环及交互的使用

第三章 循环及交互

1. for循环

1.1 语法结构
bash 复制代码
for    变量名      [ in 取值列表 ]
do
循环体
done
1.2 示例-自动循环创建/删除10个用户
bash 复制代码
[root@shell-test ~]# vim for_user.sh
#!/bin/bash
read -p "新建/删除10个用户(create/delete)选择方式:" select
if [ "$select" = "create" ]
then
        for x in {1..10}
        do
                useradd user$x
        done
        wait
        echo "10个用户已创建完毕...."
        tail -n 10 /etc/passwd
else
        for x in {1..10}
        do
                userdel -r user$x
        done
        wait
        echo "10个用户已删除完毕...."
        tail -n 10 /etc/passwd
fi
1.3 示例-在线主机Ping测试
1.3.1 常规ping测试脚本
bash 复制代码
[root@shell-test ~]# vim ping-1.sh
#!/bin/bash
read -p "请输入你要测试的主机IP: " ip
ping -c1 -W1 $ip &> /dev/null
if [ $? -eq 0 ]
then
        echo "$ip" | tee -a ip-yes.txt
        echo "$ip在线,IP地址已存至 ip-yes.txt"
else
        echo "$ip不在线,已退出。"
fi
1.3.2 循环+并发
bash 复制代码
[root@shell-test ~]# vim ping-2.sh
#!/bin/bash
>ip.txt         #清空记录文本

for i  in {2..254}
do
{
ip=172.25.254.$i
ping -c1 -W1 $ip &> /dev/null
if [ $? -eq 0 ] ;then
        echo "$ip" |tee -a ip.txt
fi
}&      # 后台执行
done
wait    # 等待前一个程序执行完毕。在执行下一个命令。
echo "finishi...."
1.4 示例-通过用户列表文件创建用户
bash 复制代码
[root@shell-test ~]# cat > user.txt <<EOF
> dhj
> jky
> yyc
> lx
> EOF

[root@shell-test ~]# vim new_user.sh
#!/bin/bash
for i in `cat user.txt`
do
        useradd $i
        echo "$i已经被创建。"
done

[root@shell-test ~]# chmod +x new_user.sh

[root@shell-test ~]# ./new_user.sh
dhj已经被创建。
jky已经被创建。
yyc已经被创建。
lx已经被创建。

说明:升级

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

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

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

启动循环创建用户

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

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

bash 复制代码
#!/bin/bash
pass=123456

if [ $# -eq 0 ]
then
        echo "filename不能为空,例下:"
        echo "$0 filename"
        echo "程序已退出...请重试..."
        exit
fi

if [ ! -f "$1" ]
then
        echo "请换成文件格式,谢谢"
        exit
fi


for i in `cat $1`
do
        id $i &> /dev/null
        if [ $? -eq 0 ]
        then
                echo "$i已经被创建,无需进行创建"
        else
                useradd $i
                echo "$pass" | passwd --stdin $i  &> /dev/null
                echo "$i已经被创建,密码为$pass"

        fi
done
1.5 示例-使用for循环实现批量主机root密码的修改
bash 复制代码
[root@shell-test ~]# ssh-keygen
[root@shell-test ~]# ssh-copy-id 172.25.254.61
[root@shell-test ~]# ssh-copy-id 172.25.254.62
[root@shell-test ~]# ssh-copy-id 172.25.254.63
bash 复制代码
#!/bin/bash
read -p "请您输入指定的远程主机地址聚合批量文件名(ps: ip.txt): " file
read -p "请您输入新的密码: " pass
for i in $(cat $file)
do
        {
                ping -c1 -W1 $i &> /dev/null
                echo
                if [ $? -eq 0 ]
                then
                        ssh root@$i "echo $pass | passwd --stdin root" &> /dev/null
                        if [ $? -eq 0 ]
                        then
                                echo "$i" >> ok.txt
                                echo "$i已完成修改,IP地址已存入 ok.txt"
                        else
                                echo "$i" >> error.txt
                                echo "$i出现错误,IP地址已存入 error.txt"
                        fi
                else
                        echo "$i" >> loss.txt
                        echo "$i处于离线状态,请检查,IP地址已存入 loss.txt"
                fi

        }&
done

2.while/until循环

循环次数不一定是固定的。

2.1 while语法结构及示例
bash 复制代码
while 条件测试
do
循环体
done
==当条件测试成立(条件测试为真),执行循环体
bash 复制代码
#!/bin/bash
while :
do
        let i++
        sleep 1
        echo $i
done
2.2 until语法结构及示例
bash 复制代码
until 条件测试
do
循环体
done
==当条件测试成立(条件测试为假视为成立),执行循环体
bash 复制代码
#!/bin/bash
i=0
until [ $i -eq 9 ]
do
        let i++
        sleep 1
        echo $i
done

3.expect交互

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

bash 复制代码
[root@shell-test ~]# yum install -y expect tcl tcl-devel
3.1 示例1-通过expect解决ssh交互问题
bash 复制代码
#!/usr/bin/expect
spawn ssh root@172.25.254.63
expect {
        "yes/no" { send "yes\r"; exp_continue }
        "password:" { send "root\r"}
}
interact
3.2 示例2-公钥推送
bash 复制代码
#!/bin/bash
>  ip.txt

rpm -q expect &> /dev/null
if [ $? -ne 0 ]
then
        yum install -y expect &> /dev/null
fi

if [ ! -f ~/.ssh/id_rsa ]
then
        ssh-keygen -P "" -f ~/.ssh/id_rsa &> /dev/null
fi

echo
echo "前置环境执行完毕...开始记录"

for i in {3..254}
do
        {
                ip=172.25.254.$i
                ping -c1 -W1 $ip &> /dev/null
                if [ $? -eq 0 ]
                then
                        echo "$ip" >> ip.txt
/usr/bin/expect << EOF &> /dev/null
set timeout 10
spawn ssh-copy-id root@$ip
expect {
"yes/no" { send "yes\r"; exp_continue }
"password:" { send "root\r" }
eof
}
expect eof
EOF
                fi
        }&
done
wait
echo "Finish....."
相关推荐
Android系统攻城狮17 分钟前
Linux FFmpeg深度解析之avcodec_flush_buffers调用流程与实战(十九)
linux·运维·服务器·ffmpeg·车载音视频·ffmpeg音视频进阶
水饺编程1 小时前
第2章:Linux 基础,解压缩【.tar.bz2】压缩包文件
linux·c语言·汇编
Zevalin爱灰灰2 小时前
Linux入门第二部分(ARM裸机篇) 第二章 Cortex-A7 MPCore架构与ARM汇编基础
linux·汇编·arm开发·嵌入式
倔强的石头1062 小时前
【Linux指南】进程通信系列(七):System V 信号量 —— 同步互斥的内核原语
linux·运维·服务器
GeW2 小时前
从"补短板"到"强优势"Linux与数据库认证成为产业跃迁人才支点
linux·数据库
PellyKoo4 小时前
【Ubuntu】GTX 1080 Ti 显卡占用为0但功率高达60W的排查与解决
linux·运维·ubuntu
Fruiticecake5 小时前
epoll 回显服务器是怎么工作的:从 accept 队列到就绪链表,以及它和 select / poll 的区别
linux
承渊政道5 小时前
Linux网络学习【从NAT与代理服务理解网络转发、探索内网穿透原理、再到认识DNS与ICMP、最后动手部署并测试内网穿透】
linux·网络·学习·内网穿透·dns·nat
重生之小比特5 小时前
【Linux系统】17 库制作与原理(下)
linux·运维·服务器
weixin_450907285 小时前
[ZYNQ Linux] VCU使用
linux·zynq