Shell脚本批量运维多台住宅服务器集群
家里有多台树莓派、旧笔记本或者NAS?
每次升级、查硬盘、重启都要一台台ssh上去敲命令,时间一长确实够累。
用Shell脚本批量处理,把重复工作交给一行循环,一次写完,后面只用跑一条命令就行。
这篇文章面向完全没写过脚本的朋友,整个过程就四步:配好SSH钥匙、写好主机清单、写一个循环脚本、验证一下。
不需要复杂工具,纯自带命令。
第一步:准备好服务器列表和SSH钥匙
批量管理的前提是能无密码登录每台机器。
先在本地电脑生成密钥对:
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -N ""
接着把公钥复制到每台服务器上。
假如你有三台机器IP为192.168.1.10、192.168.1.11、192.168.1.12,执行:
ssh-copy-id 192.168.1.10
ssh-copy-id 192.168.1.11
ssh-copy-id 192.168.1.12
按提示输入密码。
免密登录配置完成后,在本地新建一个文本文件 servers.txt,把IP一行一个写进去:
192.168.1.10
192.168.1.11
192.168.1.12
如果服务器用域名或别名也可以,只要ssh能直接连上。
第二步:写一个能跑通所有机器的循环脚本
打开终端,用 vim 或 nano 创建一个脚本文件,比如 batch.sh:
#!/bin/bash
# 批量执行命令到多台服务器
# 使用方法:bash batch.sh "uptime"
SERVERS=$(cat servers.txt)
CMD="$*"
if [ -z "$CMD" ]; then
echo "用法: $0 <命令>"
exit 1
fi
for HOST in $SERVERS
do
echo "========== $HOST =========="
ssh "$HOST" "$CMD"
done
保存后赋予执行权限 chmod +x batch.sh。
现在你可以用一条命令查看所有机器的运行时间和磁盘:
./batch.sh "uptime && df -h | grep /$"
输出会按服务器分组显示,一目了然。
如果想批量更新系统包,可以换成:
./batch.sh "sudo apt update && sudo apt upgrade -y"
新手最容易踩的四个坑
- SSH免密不生效:检查
~/.ssh/authorized_keys权限是否600,父目录.ssh权限是否700。可以用ssh -v 192.168.1.10看报错。 - sudo命令需要交互:部分机器sudo需要输入密码。解决办法是在每台服务器上给当前用户配置免密码sudo:编辑
/etc/sudoers文件,添加youruser ALL=(ALL) NOPASSWD: ALL。 - 主机名解析超时:如果
/etc/hosts未配置,ssh会尝试DNS查询导致延迟。建议服务器数量少时直接使用IP,或在本地hosts文件里写死。 - 循环中断不想等:如果某台机器ssh连不上,脚本会卡住。可以加个超时参数:
ssh -o ConnectTimeout=5 "$HOST" "$CMD"。
验证:一键检查所有机器状态
写一个简单的验证脚本 check_all.sh:
#!/bin/bash
./batch.sh "echo '主机名: $(hostname)' && free -h | grep Mem && uptime -p"
执行后,你会看到类似输出:
========== 192.168.1.10 ==========
主机名: server1
Mem: 3.7G total, 1.2G used
up 2 weeks, 3 days
========== 192.168.1.11 ==========
主机名: media-nas
Mem: 7.6G total, 2.0G used
up 1 month, 5 days
...
如果所有机器都正常返回信息,说明批量脚本已经生效。
以后需要执行任何命令,直接调用 ./batch.sh "你的命令" 就行。
如果服务器集群数量超过几十台,建议加上日志记录和错误重试,但上面的基础脚本已经够家庭环境使用。
高频操作还可以通过 crontab 定时跑一遍,比如每天早上自动检查磁盘空间,如果超过80%就发邮件提醒。
如果你在配置过程中遇到SSH连接失败或sudo卡住的情况,优先回看“避坑”部分的命令和权限设置,大多数问题都可以解决。
掌握这个思路后,再配合scp、rsync等工具,管理几百台住宅服务器也会很轻松。