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 root@192.168.40.135    \\使用spawn开启脚本和命令会话
​
expect {    \\实现交互过程
        "yes/no" { send "yes\r"; exp_continue }    \\等待用户输入,yes则继续
        "password:"{ send "123456\r" }    
}
interact
​
\\实现效果
[root@localhost ~]# ./expect_ssh01.sh 
spawn ssh root@192.168.40.135
​
Authorized users only. All activities may be monitored and reported.
root@192.168.40.135'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 root@192.168.40.156:/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.
root@192.168.40.156'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
root@192.168.40.156'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 
相关推荐
乘云数字DATABUFF2 天前
5分钟部署开源APM Databuff:OpenTelemetry全链路追踪入门实战
运维·后端
荣--3 天前
一键部署不是为了省时间 —— 它是把"买来的 PaaS"变成"自己的平台"的拐点
运维·zabbix·工程化·一键部署·平台化·边界设计
江华森4 天前
动手实战学 Docker — 从零到集群编排完全指南
运维
Avan_菜菜4 天前
FRP 内网穿透完整实战:从 HTTP 映射到 HTTPS 自签代理
运维·nginx·https
SelectDB5 天前
Litefuse 开源并推出单进程轻量模式,25 秒就能跑起来的 Agent 可观测与评估平台
运维·后端·自动化运维
XIAOHEZIcode7 天前
Linux系统鼠标偏移常见原因以及修复方案
linux·运维·游戏
用户0328472220707 天前
如何搭建本地yum源(上)
运维
大树8810 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠10 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
LDR00610 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言