【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小辣椒2 天前
TShark:Wireshark CLI 功能
linux
A小辣椒2 天前
TShark:基础知识
linux
AlfredZhao2 天前
OCI 明明分配了 200G 系统盘,为什么 df 只看到 30G?
linux·oci
AlfredZhao3 天前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户9718356334663 天前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪3 天前
linux 拷贝文件或目录到指定的位置
linux
摇滚侠4 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
bush44 天前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行5204 天前
Linux 11 动态监控指令top
linux
不会C语言的男孩4 天前
Linux 系统编程 · 第 8 章:进程基础
linux·c语言