【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....."
相关推荐
小张同学a.7 小时前
LAMP架构2
linux·运维·网络·架构·负载均衡
千河殇 多想和她7 小时前
如何在Reaonix中使用CodeGraph以及CodeGraph效果实测经验分享
linux·运维·ubuntu
躺不平的理查德7 小时前
CMAKE备忘录
linux·运维·服务器
面对疾风叭!哈撒给8 小时前
Linux ARM架构的docker和docker-compose离线安装
linux·docker·架构
阿虎儿8 小时前
Linux 下为局域网 IP(如 192.168.1.100)打造不受浏览器警告的自签名 SSL/TLS 证书
linux·安全·https
小王C语言9 小时前
虚拟机开机过程中关机,再次开机没有分配 IP
linux·网络·tcp/ip
薛定谔的悦9 小时前
光储系统 AEMS 模块的光伏控制模式设计
linux·能源·储能·bms
码农客栈9 小时前
U-Boot详解(三)之启动流程详解
linux·uboot
say_fall9 小时前
【Linux系统编程】文件操作基础:C标准库、系统调用、fd是什么和fd与FILE*的关系
android·linux·c语言
邪修king10 小时前
Re:Linux系统篇(六):动静态库 & 链接机制【完整透彻版】
linux·运维·服务器