批量执行linux命令
1、批量执行linux命令
范例-shell版-linux批量执行命令(基于免密环境的)-2024.5.22

说明
这个脚本执行的前提是:
脚本放置机器已经做好了对目标机器的免密配置;
另外,这个脚本是经过实际工作验证成功的;
脚本内容
ip
1192.168.1.1
2192.168.1.2
ntp.sh
1#!/bin/bash
2
3# 打开文件
4file="ip"
5
6# 使用while循环逐行读取文件内容
7while IFS= read -r line
8do
9 echo "$line"
10
11done < "$file"
命令内容:
1for i in `bash ntp.sh`; do echo $i ;date; echo -e "\n"; done
2
3for i in `bash ntp.sh`; do echo $i ;date -s "2024-05-21 01:45:00"; echo -e "\n"; done
4
5for i in `bash ntp.sh`; do echo $i ;hwclock -w; echo -e "\n"; done
6
7for i in `bash ntp.sh`; do echo $i ;hwclock; echo -e "\n"; done
8
9for i in `bash ntp.sh`; do echo $i ;service cas_mon restart; echo -e "\n"; done
10
11for i in `bash ntp.sh`; do echo $i ;ntpq -p; echo -e "\n"; done
执行方法
将ip、ntp.sh放到做了免密的那台服务器上
执行如下命令:
1for i in `bash ntp.sh`; do echo $i ;date; echo -e "\n"; done
2
3for i in `bash ntp.sh`; do echo $i ;date -s "2024-05-21 01:45:00"; echo -e "\n"; done
4
5for i in `bash ntp.sh`; do echo $i ;hwclock -w; echo -e "\n"; done
6
7for i in `bash ntp.sh`; do echo $i ;hwclock; echo -e "\n"; done
8
9for i in `bash ntp.sh`; do echo $i ;service cas_mon restart; echo -e "\n"; done
10
11for i in `bash ntp.sh`; do echo $i ;ntpq -p; echo -e "\n"; done
脚本位置
链接:https://pan.baidu.com/s/198_50XPWkLOMDwopEcCyUw?pwd=t9sk
提取码:t9sk
范例-shell版-linux批量执行命令(基于免密环境的)-2024.5.22

总结
这个方法虽然可行,但是一般环境是不可能存在免密的,如果有免密,那么ansible会是优先选择的;
相比而言,python脚本更适合实际工作使用的!
v4-2023.9.22-最新脚本-测试成功-荐
范例:批量远程linux机器基于不同ip配置不同信息 & 批量执行linux命令(测试成功)

python脚本(测试成功)
1.需求背景
有个需求:可以批量修改一些linux机器的信息,而这些信息是变化的,是基于不同ip有不同属性的。该如何通过shell/python脚本来实现?
脚本说明:
- 批量修改主机名;
- 批量执行linux命令;
2.编写思路
打算利用python编写这个模块。
远程ssh linux机器–>ssh模块;
基于ip信息配置不同的属性内容–>感觉需要有2个ip.txt文件,然后需要有2个for循环;
最后加上异常判断这个步骤;
这个需求实现应该不难,在原来基础上修改下即可,但是最终写出来就优点吃力了,对自己而言。
3.使用方法
- 前提环境
目标机器是linux,且可ssh;
本地要具备python环境;
- 测试时间
2022年12月23日(测试成功)
- 测试环境
winodws笔记本电脑,目标linux机器;
测试脚本版本:v1-2022.12.23
- 测试方法
(1)先查看2台测试机器的原主机名:

(2)开始执行脚本:

(3)验证:符合预期

- 2022年12月27日14:40:17 更新使用方法😘
可以同时执行2条命令就好:

4.脚本位置
链接:https://pan.baidu.com/s/1zgWNqxnN077hZMmiCMAMhw?pwd=jrcj 提取码:jrcj
1、批量执行linux命令

脚本详细内容:
ip.txt
1/192.168.1.1/
2/192.168.1.2/
linuxshell.py
1import paramiko
2import sys
3
4def ssh_exec_cmd(hostname, port, username, password, command):
5 # 创建SSH客户端
6 ssh = paramiko.SSHClient()
7 # 允许连接不在know_hosts文件中的主机
8 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
9 # 连接服务器
10 ssh.connect(hostname=hostname, port=port, username=username, password=password)
11 # 执行命令
12 stdin, stdout, stderr = ssh.exec_command(command)
13 # 获取命令结果
14 cmd_result = stdout.read()
15 # 关闭连接
16 ssh.close()
17 # 返回结果
18 return cmd_result.decode()
19
20#注意:
21# 命令列表(截取掉第一个元素)
22cmd_args = sys.argv[1:]
23# 把列表里的元素用空格连接,组成命令
24cmd = ' '.join(cmd_args)
25
26
27# for循环遍历列表
28for server in open(r'ip.txt'):
29 ip=server.split("/")[1]
30 # value=server.split("/")[2]
31 # print(ip)
32 # print(value)
33
34
35 # 执行命令
36 result = ssh_exec_cmd(hostname=ip, port=22, username='root', password='123456',command="hostname")
37 # result = ssh_exec_cmd(hostname=ip, port=22, username='root', password='password',command='sh test.sh') #执行脚本也是没问题的
38 # 输出结果
39 print(ip,"is ok !!!")
40 # print(result)
v3-myssh_v2脚本-20210104(更新后)
1、首先,请确认python环境是否已安装相关模块
(如无安装,请利用pip install 模块名安装,前提是要能联网;或者利用离线方式安装相应模块)
2、如何使用此脚本?
(1)填写目标ip、账户名、密码、ssh端口:
(2)填写需要在linux机器上需要被执行的命令
特别注意:目前此版本需要保证节点ip都是可通的才行。(否则程序会卡主不往下执行的)
观察输出
范例1:测试执行单个命令:可以执行成功。
单个命令可以用;隔开;
范例2:测试linux上的某个脚本:可以执行成功。
3、次脚本需要进行优化的地方
==(1)最大问题:如果某个服务器ip不通的话,程序运行就会卡住。==
如何做到,遇到ip不通的或者执行失败的机器输出到对应的文件,执行成功的报success提示:(这种才是相对的智能化)
测试3台机器如下:
3个ip都通时,测试效果如下:
使其中一个ip不通时,再次进行测试:
测试现象,当其中一个节点不通时,后续节点没有出现在控制台上,这个就是个bug了。理论是要经过一段时间跳过去的才对。。。
(2)cmd输出的命令速度很慢。
(3)缺点:命令中不能使用变量
v2-linuxCmd脚本(别人分享-有bug)
无备注
v1-myssh-Python脚本(网上脚本)
1、首先,请确认python环境是否已安装相关模块
(如无安装,请利用pip install 模块名安装,前提是要能联网;或者利用离线方式安装相应模块)

2、如何使用此脚本?
1 填写目标ip、账户名、密码、ssh端口:

2 填写需要在linux机器上需要被执行的命令

3 观察输出
需要修改的2处地方修改完后,直接运行程序,验证结果。
4 案例:测试执行单个命令:可以执行成功。
#单个命令可以用;隔开;

5 案例:测试linux上的某个脚本:可以执行成功。
#Linux上的脚本:

#

3、次脚本的缺点
6 最大问题:如果某个服务器ip不通的话,程序运行就会卡主。


7 cmd输出的命令速度很慢:。。。。。。

8 缺点:命令中不能使用变量;

9 cmd在输出时没有关于所属主机的提示:

1
2、批量修改主机名
ip.txt
1/192.168.1.1/newName1/
2/192.168.1.2/newName2/
ModifyHostname.py
1import paramiko
2import sys
3
4def ssh_exec_cmd(hostname, port, username, password, command):
5 # 创建SSH客户端
6 ssh = paramiko.SSHClient()
7 # 允许连接不在know_hosts文件中的主机
8 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
9 # 连接服务器
10 ssh.connect(hostname=hostname, port=port, username=username, password=password)
11 # 执行命令
12 stdin, stdout, stderr = ssh.exec_command(command)
13 # 获取命令结果
14 cmd_result = stdout.read()
15 # 关闭连接
16 ssh.close()
17 # 返回结果
18 return cmd_result.decode()
19
20#注意:
21# 命令列表(截取掉第一个元素)
22cmd_args = sys.argv[1:]
23# 把列表里的元素用空格连接,组成命令
24cmd = ' '.join(cmd_args)
25
26
27# for循环遍历列表
28for server in open(r'ip.txt'):
29 ip=server.split("/")[1]
30 value=server.split("/")[2]
31 # print(ip)
32 # print(value)
33
34
35 # 执行命令
36 result = ssh_exec_cmd(hostname=ip, port=22, username='root', password='123456',command="hostnamectl --static set-hostname {}".format(value))
37 result = ssh_exec_cmd(hostname=ip, port=22, username='root', password='123456',command="hostname")
38 # result = ssh_exec_cmd(hostname=ip, port=22, username='root', password='password',command='sh test.sh') #执行脚本也是没问题的
39 # 输出结果
40 print(ip,"has be modified success !!!")
41 print(result)
1
3、批量修改ip
过程
1sed -i s"/^PASS_MIN_LEN/#PASS_MIN_LEN/g" login.defs
2sed -i '/#PASS_MIN_LEN/a\PASS_MIN_LEN 88' login.defs
1、先改主机名称
2、改ip
1[root@gjjz126158 network-scripts]# cat ifcfg-bond0
2DEVICE=bond0
3TYPE=Ethernet
4ONBOOT=yes
5BOOTPROTO=static
6IPADDR=10.128.xx.xx
7NETMASK=255.255.255.0
8GATEWAY=10.128.xx.1
9IPV6INIT=no
10BONDING_MASTER=yes
11BONDING_OPTS="mode=1 miimon=100"
12
13/etc/sysconfig/network-scripts/ifcfg-bond0
14
15
16
17
18sed -i s"/^IPADDR/#IPADDR/g" /etc/sysconfig/network-scripts/ifcfg-bond0
19sed -i s"/^NETMASK/#NETMASK/g" /etc/sysconfig/network-scripts/ifcfg-bond0
20sed -i s"/^GATEWAY/#GATEWAY/g" /etc/sysconfig/network-scripts/ifcfg-bond0
21
22
23#echo "IPADDR=10.130.x.x" >> /etc/sysconfig/network-scripts/ifcfg-bond0
24echo "IPADDR={}.format(newIP)" >> /etc/sysconfig/network-scripts/ifcfg-bond0
25echo "NETMASK=255.255.255.0" >> /etc/sysconfig/network-scripts/ifcfg-bond0
26echo "GATEWAY=10.130.x.1" >> /etc/sysconfig/network-scripts/ifcfg-bond0


脚本得优化下。。
第2个机器没生效。。。


改进:删除干净ip配置(测试失败)
1sed命令如何删除以某个单词开头的行?
2使用sed命令删除以某个单词开头的行,可以使用正则表达式来匹配。下面是一个示例命令:
3
4sed '/^word/d' file.txt
5在上述命令中,"word"是你要删除的行开头的单词,"file.txt"是你要操作的文件名。该命令将删除文件中以"word"开头的所有行。请注意,这里的匹配是区分大小写的。如果你想不区分大小写地进行匹配,可以使用sed命令的-i选项来进行不区分大小写的替换:
6
7sed -i '/^word/d' file.txt
8上述命令将直接在文件中进行替换操作。如果你想要备份原始文件,可以在-i选项之后添加一个文件扩展名,例如:
9
10sed -i.bak '/^word/d' file.txt
11上述命令将在进行替换操作的同时备份原始文件,并添加".bak"作为文件扩展名。
12
13
14汇总:
15sed '/^word/d' file.txt
1
2[root@xxxxx network-scripts]# cat ifcfg-bond0
3DEVICE=bond0
4TYPE=Ethernet
5ONBOOT=yes
6BOOTPROTO=static
7IPADDR=10.128.xxx.xxx
8NETMASK=255.255.255.0
9GATEWAY=10.128.xxxx.1
10IPV6INIT=no
11BONDING_MASTER=yes
12BONDING_OPTS="mode=1 miimon=100"
13
14/etc/sysconfig/network-scripts/ifcfg-bond0
15
16
17
18
19sed '/^IPADDR/d' /etc/sysconfig/network-scripts/ifcfg-bond0
20sed '/^NETMASK/d' /etc/sysconfig/network-scripts/ifcfg-bond0
21sed '/^GATEWAY/d' /etc/sysconfig/network-scripts/ifcfg-bond0
22
23
24#echo "IPADDR=10.130.x.x" >> /etc/sysconfig/network-scripts/ifcfg-bond0
25echo "IPADDR={}.format(newIP)" >> /etc/sysconfig/network-scripts/ifcfg-bond0
26echo "NETMASK=255.255.255.0" >> /etc/sysconfig/network-scripts/ifcfg-bond0
27echo "GATEWAY=10.130.x.1" >> /etc/sysconfig/network-scripts/ifcfg-bond0

失败:

改进:重启网络(测试失败)
如何让一条linux命令放在后台执行?
要将一条Linux命令放在后台执行,你可以在命令的末尾加上&符号。这将使命令在后台运行,而不会阻塞终端,让你可以继续在终端输入其他命令。
例如,假设你要运行一个长时间执行的脚本文件script.sh,你可以这样执行它:
1./script.sh &
在这个例子中,script.sh将会在后台运行,不会阻塞当前的终端会话。你可以继续在终端输入其他命令,而script.sh会持续在后台执行。
请注意,一旦你将命令放在后台执行,它将不再在终端上显示输出。如果你希望将输出保存到文件中,可以使用重定向操作符>将输出写入到文件中,例如:
1./script.sh > output.txt &
上述命令将脚本的输出保存到output.txt文件中,同时将脚本放在后台执行。

最终脚本
ChangeIp.py
1import paramiko
2import sys
3
4def ssh_exec_cmd(hostname, port, username, password, command):
5 # 创建SSH客户端
6 ssh = paramiko.SSHClient()
7 # 允许连接不在know_hosts文件中的主机
8 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
9 # 连接服务器
10 ssh.connect(hostname=hostname, port=port, username=username, password=password)
11 # 执行命令
12 stdin, stdout, stderr = ssh.exec_command(command)
13 # 获取命令结果
14 cmd_result = stdout.read()
15 # 关闭连接
16 ssh.close()
17 # 返回结果
18 return cmd_result.decode()
19
20#注意:
21# 命令列表(截取掉第一个元素)
22cmd_args = sys.argv[1:]
23# 把列表里的元素用空格连接,组成命令
24cmd = ' '.join(cmd_args)
25
26
27# for循环遍历列表
28for server in open(r'ip.txt'):
29 ip=server.split("/")[1]
30 value=server.split("/")[2]
31 newIP=server.split("/")[3]
32 # print(ip)
33 # print(value)
34
35 #更改ip
36 result = ssh_exec_cmd(hostname=ip, port=5151, username='root', password='你的密码',command='sed -i s"/^IPADDR/#IPADDR/g" /etc/sysconfig/network-scripts/ifcfg-bond0')
37 result = ssh_exec_cmd(hostname=ip, port=5151, username='root', password='你的密码',command='sed -i s"/^NETMASK/#NETMASK/g" /etc/sysconfig/network-scripts/ifcfg-bond0')
38 result = ssh_exec_cmd(hostname=ip, port=5151, username='root', password='你的密码',command='sed -i s"/^GATEWAY/#GATEWAY/g" /etc/sysconfig/network-scripts/ifcfg-bond0')
39 result = ssh_exec_cmd(hostname=ip, port=5151, username='root', password='你的密码',command='echo "IPADDR={}" >> /etc/sysconfig/network-scripts/ifcfg-bond0'.format(newIP))
40 result = ssh_exec_cmd(hostname=ip, port=5151, username='root', password='你的密码',command='echo "NETMASK=255.255.255.0" >> /etc/sysconfig/network-scripts/ifcfg-bond0')
41 result = ssh_exec_cmd(hostname=ip, port=5151, username='root', password='你的密码',command='echo "GATEWAY=xxxxx.1" >> /etc/sysconfig/network-scripts/ifcfg-bond0')
42 result = ssh_exec_cmd(hostname=ip, port=5151, username='root', password='你的密码',command='systemctl restart network')
43 print(ip," ok")

当时重启网络命令测试失败,最后直接重启服务器了。
1

