【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....."
相关推荐
AnalogElectronic3 分钟前
linux 测试网络和端口是否连通的命令详解
linux·网络·php
Edward1111111138 分钟前
4月28日防火墙问题
linux·运维·服务器
子琦啊1 小时前
【算法复习】字符串 | 两个底层直觉,吃透高频题
linux·运维·算法
AOwhisky2 小时前
Kubernetes 学习笔记:集群管理、命名空间与 Pod 基础
linux·运维·笔记·学习·云原生·kubernetes
小龙在慢慢变强..3 小时前
目录结构(FHS 标准)
linux·运维·服务器
2035去旅行3 小时前
嵌入式开发,如何选择C标准库
linux·arm开发
刘延林.3 小时前
win11系统下通过 WSL2 安装Ubuntu 24.04 使用RTX 5080 GPU
linux·运维·ubuntu
CodeOfCC4 小时前
Linux 嵌入式arm64安装openclaw
linux·运维·服务器
宵时待雨5 小时前
linux笔记归纳3:linux开发工具
linux·运维·笔记
magrich5 小时前
安装NoMachine并解决无外接显示器桌面黑屏
linux·运维·服务器