家用住宅主机Shell脚本批量运维多台机器
为什么需要用Shell脚本批量管理多台家用主机
家里有树莓派、旧笔记本搭建的NAS、软路由、或者几台跑服务的工控机,每次更新系统、检查负载、同步文件都得一台台登上去执行,非常低效。
用Shell脚本配合SSH免密,写一个脚本就能一次发给所有机器执行,节省大量时间。
本文从零开始,覆盖准备、脚本编写、分发、避坑和验证,让你看完就能用起来。
前置准备:确定机器列表和SSH免密登录
准备清单
- 所有主机都安装Linux系统(Ubuntu/Debian/CentOS均可,原理通用)
- 你有一台“控制机”(可以用主力电脑或其中一台高性能主机)
- 所有主机与控制机在同一个局域网内,能相互ping通
- 每台主机已开启SSH服务(默认通常已开启,未开启可执行
sudo systemctl start sshd启动并设置开机自启)
配置SSH免密登录(一步到位)
在控制机上执行以下命令,生成本机SSH密钥(如果已有则跳过):
ssh-keygen -t rsa -b 4096 -N "" -f ~/.ssh/id_rsa
然后将公钥复制到每台目标主机(假设目标主机的用户名为pi,IP为192.168.1.101):
ssh-copy-id pi@192.168.1.101
按提示输入一次目标主机的密码,以后再连接就不再需要密码。
对每一台要管理的主机都执行一次上述复制命令。
编写批量运维脚本:以批量更新系统为例
创建一个脚本文件,比如 batch_update.sh,内容如下:
#!/bin/bash
# 定义主机列表(IP地址或主机名,每行一个)
HOSTS=(
"192.168.1.101"
"192.168.1.102"
"192.168.1.103"
"nas.local" # 也可用主机名
)
# 定义要在每台机器上执行的命令
CMD="sudo apt update && sudo apt upgrade -y"
# 循环遍历主机并执行
for HOST in "${HOSTS[@]}"; do
echo "========== 正在处理 $HOST =========="
ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 "$USER@$HOST" "$CMD"
if [ $? -eq 0 ]; then
echo "$HOST 执行成功"
else
echo "$HOST 执行失败,请检查"
fi
echo ""
done
关键点说明
-o StrictHostKeyChecking=no:首次连接跳过指纹确认,避免交互卡住-o ConnectTimeout=10:网络超时设置,防止卡在连不上的主机- 脚本中
$USER自动使用当前控制机的用户名,如果目标主机用户名不同,需要替换为对应用户名,例如pi@$HOST
给脚本添加执行权限后运行:
chmod +x batch_update.sh
./batch_update.sh
批量运维的常见避坑指南
1. 权限问题:避免sudo需要密码
许多管理员命令需要sudo,而默认情况下SSH执行sudo需要交互式输入密码,脚本会卡住。
解决方法:在每台目标主机上编辑 /etc/sudoers(使用 visudo 命令),添加一行:
username ALL=(ALL) NOPASSWD: ALL
将username替换为登录用户名,保存后即可免密码sudo。
2. 网络兼容:部分机器可能掉线或超时
如果某台主机关机或网络断开,脚本会一直等待超时。
已在上文加了 ConnectTimeout,也可以对失败主机单独记录,后期排查。
3. SSH端口不同
如果某些主机SSH端口不是默认22,可以修改 CMD 部分在ssh命令后加 -p 端口号,或者在 HOSTS 中用 -p 参数方式,更灵活的做法是使用配置文件。
4. 日志与输出重定向
建议将每台机器的输出分别保存,便于事后检查。
可在ssh命令后用 >> log_${HOST}.txt 2>&1 追加日志。
效果验证:确认脚本正确执行
执行脚本后,可以看到类似输出:
========== 正在处理 192.168.1.101 ==========
[sudo] password for pi: (如果已配置免密码sudo,这里不会出现)
... 更新过程 ...
192.168.1.101 执行成功
========== 正在处理 192.168.1.102 ==========
...
也可以通过登录其中一台主机验证包是否已更新:
dpkg -l | grep openssh # 检查ssh版本是否更新
如果所有主机都显示成功且无报错,批量运维脚本就生效了。
下次需要执行其他命令,只需修改 CMD 变量的内容即可。
常见问题解答
Q:复制公钥时提示“Permission denied”怎么办?
A:检查目标主机的SSH服务是否运行,以及/home/用户名/.ssh目录权限是否正确(通常为755),也可以尝试使用 ssh -vvv 查看详细错误。
Q:脚本执行到某台机器卡住不动?
A:按下Ctrl+C中止,先单独ssh那台机器,检查是否网络不通或ssh服务无响应。
Q:如何在批量执行前先在单台机器测试命令?
A:临时去掉循环,直接写 ssh 用户@IP "命令" 测试,确认正常后再放回循环。
总结
通过SSH免密和Shell脚本的组合,家用多台主机的批量运维变得十分简单。
核心步骤是:配置免密 → 编写包含主机列表和执行命令的脚本 → 处理sudo免密码和超时 → 执行并验证。
建议将脚本保存好,后续只需修改命令就能重复使用。
如果你需要更高级的功能,比如按条件过滤主机、并行执行加速、错误重试等,可在本文基础上扩展。
遇到问题时,优先检查SSH连通性和sudo权限配置。