【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....."
相关推荐
菜鸟z级2 小时前
在新电脑装ubuntu包
linux·运维·ubuntu
一个人旅程~2 小时前
旧笔记本电脑安装win10精简版LTSB&win10LTSC&linuxmint作为三系统的操作指导书(以DELL n4020为例)
linux·windows·经验分享·电脑
蓝牙先生2 小时前
22_backlightLinux内核模块
linux·c语言
木鱼布2 小时前
CentOS7配置vsftpd
linux·运维
my_styles2 小时前
linux系统下安装 tengine / 宝兰德等国产信创中间件和闭坑
linux·运维·服务器·spring boot·nginx·中间件
yy_xzz2 小时前
【Linux开发】I/O 复用:select 模型
linux·c++·select
EnglishJun3 小时前
ARM嵌入式学习(十八)--- Linux的内核编译和启动
linux·运维·学习
魔都吴所谓3 小时前
【Ubuntu】离线环境下Git LFS(deb包)安装与验证完整教程
linux·git·ubuntu
w6100104663 小时前
CKA-2026-StorageClass
linux·运维·服务器·cka·storageclass
吕司3 小时前
Linux线程同步
linux·服务器·开发语言