Shell循环(二)

expect交互式公钥推送

expect实现非交互登录

  • expect用于自动化控制交互式应用程序。
  • expect脚本通常需要用户输入或确认等自动化任务。

例:使用expect实现SSH非交互登录

复制代码
[root@localhost ~]# yum install expect
[root@localhost ~]# which expect
/usr/bin/expect
[root@localhost ~]# vim expect_ssh01.sh
#!/usr/bin/expect    \\使用expect作为命令解释器
spawn ssh [email protected]    \\使用spawn开启脚本和命令会话
​
expect {    \\实现交互过程
        "yes/no" { send "yes\r"; exp_continue }    \\等待用户输入,yes则继续
        "password:"{ send "123456\r" }    
}
interact
​
\\实现效果
[root@localhost ~]# ./expect_ssh01.sh 
spawn ssh [email protected]
​
Authorized users only. All activities may be monitored and reported.
[email protected]'s password: Jan16@gdcp
​
​
Authorized users only. All activities may be monitored and reported.
Web console: https://localhost:9090/
​
Last login: Mon Jul 15 15:21:40 2024
[root@localhost ~]# ip add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:20:c5:3a brd ff:ff:ff:ff:ff:ff
    inet 192.168.40.135/24 brd 192.168.40.255 scope global dynamic noprefixroute ens160
       valid_lft 1556sec preferred_lft 1556sec
    inet6 fe80::e786:f90a:9f18:cc7d/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

expect实现非交互传输文件

  • 使用expect非交互式与scp命令结合,实现scp批量传输本地不同文件到不同远程主机的不同路径。
  • 第一次scp需要做验证,同时需注意列表文件与变量的顺序。

例:

复制代码
[root@localhost ~]# touch test.txt
[root@localhost ~]# echo test.txt >> /etc/hosts
[root@localhost ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
test.txt
​
[root@localhost ~]# vim expect_scp.sh
#!/usr/bin/expect
​
set ip [lindex $argv 0]  \\脚本的第一个位置参数
set user root
set password 11223344
set timeout 5
​
#把本地目录及目录下的文件以$user这个用户批量复制到对方$ip主机上的/tmp目录下
spawn scp -r /etc/hosts $user@$ip:/tmp
expect {
        "yes/no" { send "yes\r"; exp_continue }
        "password" { send "$password\r" }
​
}
​
#当看到eof时,事情做完后结束expect,脚本退出
expect eof

执行结果:

复制代码
[root@localhost ~]# ./expect_scp.sh 192.168.40.156
spawn scp -r /etc/hosts [email protected]:/tmp
The authenticity of host '192.168.40.156 (192.168.40.156)' can't be established.
ECDSA key fingerprint is SHA256:Q8mRLuY/2Xwj2vPTpQLR/pJJzAYRnOA2BGojyhfNSJ0.
ECDSA key fingerprint is MD5:60:36:8b:21:87:22:7a:e3:03:77:63:1a:de:bb:69:1d.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.40.156' (ECDSA) to the list of known hosts.
[email protected]'s password: 
hosts                                                                100%  206   209.1KB/s   00:00 
​
192.168.40.156主机:
[root@localhost tmp]# ls
hosts                                                                    vmware-root_696-2722173465
systemd-private-651b437eb58b4b9b90b5b2b53fb44b92-chronyd.service-t4xDDM  vmware-root_712-2957059153
systemd-private-651b437eb58b4b9b90b5b2b53fb44b92-nginx.service-7lNjij

expect实现批量主机公钥推送

复制代码
[root@localhost ~]# vim getip_push_public.sh
​
#!/bin/bash
#检查是否安装了expect软件
rpm -q expect &>/dev/null
if [ $? -ne 0 ];then
        yum -y install expect
        if [ $? -eq 0 ];then
                echo "install success!"
        else
                echo "install faile!"
                exit 2
        fi
fi
#检查客户端是否生成了公钥和私钥
if [ ! -f ~/.ssh/id_rsa ];then
        ssh-keygen -P "" -f ~/.ssh/id_rsa
        if [ $? -eq 0 ] ;then
                echo "success!"
        else
                echo "fail!"
                exit 2
        fi
fi
#检查客户端能否ping通,如果能ping通就使用expect推送密钥
>ip.txt
password=Jan16@gdcp
    for i in {2..254};do
        ip=192.168.40.$i
        ping -c1 -W1 $ip  &>/dev/null
        if [ $? -eq 0 ];then
                echo "$ip" >> ip.txt
        #推送公钥,ping通一个推送一个
                /usr/bin/expect <<EOF
                set timeout 10
                spawn ssh-copy-id $ip
                expect {
                        "yes/no" { send "yes\r"; exp_continue }
                        "password:" { send "$password\r" } 
                        timeout { send_user "连接超时$ip\n"; exit 1 }
                eof { send_user "expect caught exception!\n" exit 1 }
                }
                expect eof
EOF
                result=$?
                if [ $result -ne 0 ];then
                        echo "推送密钥到$ip失败!"
                else
                        echo "推送密钥到$ip成功!"
                fi
        fi
        done
echo "finish..."
:set list #查看特殊字符(隐形字符)
:set nolist #取消查看特殊字符(隐形字符)

执行结果如下所示:

复制代码
[root@localhost ~]# ./getip_push_public.sh 
spawn ssh-copy-id 192.168.40.156
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
[email protected]'s password: 
​
Number of key(s) added: 1
​
Now try logging into the machine, with:   "ssh '192.168.40.156'"
and check to make sure that only the key(s) you wanted were added.
​
推送密钥到192.168.40.156成功!
^C^C^Z
[6]+  Stopped                 ./getip_push_public.sh
[root@localhost ~]# ssh 192.168.40.156
Last login: Fri Aug 16 04:39:28 2024 from 192.168.40.10
[root@localhost ~]# exit
logout
Connection to 192.168.40.156 closed.

for循环语句实现批量主机密码修改

复制代码
[root@localhost ~]# vim modify_password.sh
​
#!/bin/bash
read -p "Please enter a New password: " pass
echo
for ip in $(cat ip.txt)
do
        {
                ping -c1 -W1 $ip &>/dev/null
                if [ $? -eq 0 ];then
                        ssh $ip "echo $pass |passwd --stdin root"
                        if [ $? -eq 0 ];then
                                echo "$ip" >>ok_`date +%F`.txt
                        else
                                echo "$ip" >>fail_`date +%F`.txt
                        fi
                else
                        echo "$ip">>fail.txt
                fi
        }&
done
wait
echo "finish..."

执行结果如下所示:

复制代码
[root@localhost ~]# ./modify_password.sh 
Please enter a New password: 11223344
​
Changing password for user root.
passwd: all authentication tokens updated successfully.
​
[root@localhost ~]# cat ip.txt 
192.168.40.2
192.168.40.10
192.168.40.136
192.168.40.156
​
[root@localhost ~]# cat ok_2024-08-19.txt 
192.168.40.156
[root@localhost ~]# cat fail_2024-08-19.txt 
192.168.40.156
[root@localhost ~]# cat fail.txt 
192.168.40.156

for循环语句实现批量远程主机SSH配置

复制代码
[root@localhost ~]# vi modify_sshconfig.sh
​
#!/bin/bash
    for ip in `cat ip.txt`
    do
        {
        ping -c1 -W1 $ip &>/dev/null
        if [ $? -eq 0 ];then
                ssh $ip "sed -ri '/^#UsedNS/cUsedNS no' /etc/ssh/sshd_config"
                ssh $ip "sed -ri '/^GSSAPIAuthentication/cGSSAPIAuthentication no' /etc/ssh/sshd_config"
                ssh $ip "sed -ri '/^SELINUX=/cSELINUX=disabled' /etc/selinux/config"
                ssh $ip "systemctl stop firewalld;systemctl disable firewalld"
                ssh $ip "setenforce 0"
        fi 
        }&
done
wait
echo "finish..."

执行结果如下所示:

复制代码
[root@localhost ~]# ./modify_sshconfig.sh 
Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
setenforce: SELinux is disabled
finish..

注:检查脚本语法可以使用bash -n命令

复制代码
[root@localhost ~]# bash -n modify_sshconfig.sh 
相关推荐
XMYX-030 分钟前
Python 实现一个带进度条的 URL 批量下载工具(含 GUI 界面)
开发语言·python
liulilittle38 分钟前
OpenSSL 的 AES-NI 支持机制
linux·运维·服务器·算法·加密·openssl·解密
一只小小汤圆1 小时前
如何xml序列化 和反序列化类中包含的类
xml·开发语言·c#
南枝异客1 小时前
电话号码的字母组合
开发语言·javascript·算法
未来并未来1 小时前
Sentinel 流量控制安装与使用
开发语言·python·sentinel
风清再凯1 小时前
docker镜像的构建image
运维·docker·容器
饭碗、碗碗香1 小时前
【开发常用命令】:docker常用命令
linux·运维·笔记·学习·docker·容器
Halo_tjn1 小时前
Java IO
java·开发语言
我命由我123452 小时前
STM32 开发 - 中断案例(中断概述、STM32 的中断、NVIC 嵌套向量中断控制器、外部中断配置寄存器组、EXTI 外部中断控制器、实例实操)
c语言·开发语言·c++·stm32·单片机·嵌入式硬件·嵌入式
东皇太星2 小时前
Python 100个常用函数全面解析
开发语言·python