多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

统信UOS批量运维脚本实战:SSH免密、并发控制与高频异常处理

统信UOS批量运维脚本实战:SSH免密、并发控制与高频异常处理 简介统信操作系统批量激活场景下这份shell脚本可根据机器MAC地址或硬盘序列号自动匹配激活码完成系统激活主要面向需要维护大量终端的企业运维、IT管理员及系统实施人员脚本需以root权限运行并保持联网使用前须将设备MAC地址或序列号与合法激活码填入脚本映射表中仅适用于持有正版授权的批量激活场景。资源包为zip压缩格式整体仅496字节内含1个shell脚本文件结构精简无额外依赖便于直接查看和修改。目前该资源已有7814人学习下载说明批量激活需求在国产化替代项目中较为常见。脚本本身提供了自动化匹配与激活逻辑可大幅降低逐台手动激活的重复劳动同时为理解统信系统激活流程提供了可参考的脚本样例。需要注意的是该脚本不会自带任何激活码使用者必须根据自身设备信息编辑映射关系并预先准备合法的正版激活码才能在实际环境中正确执行。1. 统信UOS批量操作脚本一台台点鼠标的运维干不过一个for循环一百台预装统信UOS的国产化终端刚拆箱系统版本是UOS桌面版21.3处理器混着兆芯和AMD。有的机器需要激活有的用户密码过期要重置有的登录界面卡在黑屏有的系统盘被日志撑满。一台台用鼠标点激活码复制粘贴几百次误操作随时可能发生。批量操作脚本解决的问题就是这个把激活、重置密码、字体下发、磁盘清理这些重复操作变成同一套命令在所有机器上自动执行。本文用一个可直接改的Shell脚本骨架带你走完从SSH免密到灰度验证的全过程适合机房管理员、政企信息中心和集成商实施工程师。2. 批量操作的地基SSH免密、主机清单与并发控制先说选型UOS基于Debian体系自带OpenSSH批量操作最常见的落地方式是SSH加Shell脚本而不是在每个终端上装agent。政企环境终端数量几十到几百台装agent要过杀软白名单还要升级维护SSH是系统自带能力只要网络通就能用。Ansible也可以但它本质还是走SSH且需要控制机上有Ansible环境在离线内网里装Ansible反而是额外负担。所以这篇的核心是纯Shell批量脚本逻辑透明、依赖最少出问题也容易定位。2.1 主机清单怎么建免密与连通性预检主机清单用纯文本。IP列表放一个文件每行一个IP一个用户名一个端口便于批次拆开。首次要打通免密步骤是生成密钥、分发公钥、验证连通性。# 准备主机清单格式: IP 用户名 端口用空格分隔 # 示例: # 192.168.10.11 uosuser 22 # 192.168.10.12 uosuser 22 cat hosts.txt EOF 192.168.10.11 uosuser 22 192.168.10.12 uosuser 22 192.168.10.13 uosuser 22 EOF # 生成密钥已有则跳过 [ -f ~/.ssh/id_rsa ] || ssh-keygen -t rsa -b 4096 -N -f ~/.ssh/id_rsa # 逐台分发公钥首次需要手动输入目标机密码 while read -r ip user port; do ssh-copy-id -i ~/.ssh/id_rsa.pub -p $port ${user}${ip} done hosts.txt # 免密连通性预检所有机器执行 whoami超时 8 秒 while read -r ip user port; do timeout 8 ssh -p $port ${user}${ip} whoami \ echo [OK] $ip || echo [FAIL] $ip done hosts.txt这段代码的逻辑把主机清单做成“IP 用户名 端口”三列文本后续所有脚本都从这里读取ssh-keygen 生成4096位RSA密钥-N 表示空口令避免交互。ssh-copy-id 一次只处理一台首次需要手动确认指纹并输入密码这是唯一一次需要人工介入的地方。预检这步很多人跳过结果批量执行时有一半机器连不上白等半天。我一般会在每一批机器上先跑whoami确认免密真的通了再继续。这里有个容易被忽略的细节ssh-copy-id 在UOS上的OpenSSH版本可能略老如果提示权限太开放检查目标机~/.ssh/authorized_keys的权限是否为600家目录是否为700。写成脚本检查也可以但我在第5章会专门说这类坑。2.2 并发控制xargs -P 的正确姿势逐台执行太慢100台机器跑完一轮要十几分钟等于是手工操作的加速版而已。改用并发但要控好并发数否则sshd的MaxStartups会拒绝连接。#!/bin/bash # batch_exec.sh - 批量执行脚本通用骨架 # 用法: ./batch_exec.sh 命令字符串 [并发数] CMD$1 JOBS${2:-10} LOG_DIR./logs/$(date %Y%m%d_%H%M%S) mkdir -p $LOG_DIR export CMD LOG_DIR while read -r ip user port; do echo $ip $user $port done hosts.txt | xargs -P $JOBS -I {} bash -c set -o pipefail line$1 ip$(echo $line | cut -d -f1) user$(echo $line | cut -d -f2) port$(echo $line | cut -d -f3) if timeout 120 ssh -p $port ${user}${ip} $CMD $LOG_DIR/$ip.log 21; then echo [OK] $ip else echo [FAIL] $ip, 看 $LOG_DIR/$ip.log fi _ {} wait echo 执行完成结果见 $LOG_DIR参数说明与逻辑xargs -P $JOBS控制同时跑的SSH进程数推荐10左右太小浪费内网带宽太大会触发对端sshd的并发保护。timeout 120给单机命令一个硬性超时防止某台机器挂起拖住整批结果。set -o pipefail保证SSH退出码不被管道吞掉失败能准确反映到外层。每台机器的日志按IP命名这是排错的关键——批量脚本不是跑完就结束留痕才能回答“哪台失败、失败在哪”这两个问题。并发数不是玄学它取决于三件事控制机的文件描述符上限、目标网段带宽、目标机sshd的MaxStartups。我一般先用10跑通再看失败率决定要不要调。2.3 为什么不直接上 Ansible小批量场景的取舍政企场景里Ansible并非不能用但在这种批量操作需求下纯脚本更贴近现场。原因有三条第一Ansible需要控制机安装Python和ansible包内网离线环境经常没有第二playbook的抽象层级高现场临时改一处逻辑要查模块文档第三出问题时排错链路长而运维在实施现场最缺的就是时间。但Ansible有一个优势值得借鉴它的执行结果是结构化的每台机器成功失败一目了然。纯脚本要达到同样效果就得在脚本里做好主机清单、日志拆分、返回码判断这三件事。上面这个骨架已经覆盖了这三点并且比Ansible多了一个好处任何一条命令都能直接复制到单台机器上手动跑复现成本低。控制机和目标机之间的网络波动是批量脚本最大的不确定因素脚本里能做的只有两件事超时控制和失败重试这两点在第5章会专门展开。3. 高频场景脚本激活、重置密码与字体下发3.1 批量激活统信UOS授权导入与状态核验统信UOS的激活机制和Windows激活类似实施单位会拿到一批激活码或授权文件。手工激活要走图形界面的授权管理工具点一次要一两分钟100台就是两小时。命令行激活才是正路。常见做法是调用UOS自带的命令行授权工具uos-activation配合授权文件批量导入。各版本命令略有差异落地时先在一台机器上跑uos-activation --help确认参数再写到脚本里。# 批量激活把授权文件批量拷贝到目标机并执行激活命令 # 假设授权文件在 ./license/ 下按IP命名: 192.168.10.11.key while read -r ip user port; do keyfile./license/${ip}.key if [ -f $keyfile ]; then scp -q -P $port $keyfile ${user}${ip}:/tmp/activation.key ssh -p $port ${user}${ip} \ sudo uos-activation --import /tmp/activation.key sudo uos-activation --activate else echo [SKIP] $ip 没有对应授权文件 fi done hosts.txt逻辑和参数授权文件与目标机IP一一对应这是政企批量授权的常见交付方式scp -q静默拷贝避免进度条刷屏激活命令通过sudo执行前提是执行用户有sudo权限。命令执行完要验证不能只看返回码。验证命令通常是uos-activation --status输出里有activated字样才算激活完成。激活这步最需要注意的是家庭版和个人版的激活策略与大客户版不同。uos-activation在大客户版上走授权文件个人版可能走的是账号体系。批量脚本假设的是大客户版环境如果你手里是家庭版21.3先确认版本再跑否则会看到一堆LICENSE_INVALID报错。实施现场的惯例是新到货的机器先在仓库里完成激活和初始化再分发到工位批量脚本刚好能把这一步控制在半天内完成。3.2 批量重置密码chpasswd 与 PAM 锁定的联动“uos重置密码”是搜索热词也是现场频率最高的需求。UOS默认普通用户权限受限密码过期、忘记密码、被人误改都靠批量重置来兜底。前提是执行批量脚本的用户有sudo权限。# 批量重置普通用户密码从 passwd.txt 读入 user:password # 格式: 每行一个用户冒号分隔 cat passwd.txt EOF uosuser:NewPass2024 testuser:AnotherPass2024 EOF while read -r ip user port; do ssh -p $port ${user}${ip} \ while IFS: read -r u p; do echo $u:$p | sudo chpasswd echo [OK] $u 密码已重置; done passwd.txt done hosts.txt逻辑与参数chpasswd从标准输入读取“用户名:新密码”批量改多个用户时一次传完比逐条passwd交互效率高得多。这里有个重要细节chpasswd默认走PAM认证受密码复杂度策略约束。UOS的密码策略在/etc/pam.d/common-password里由pam_pwquality管控新密码太短或太简单会被拒。先在一台机器上测试新密码是否符合策略否则100台机器会整批失败日志里只留下模糊的Authentication token manipulation error。如果目标是批量调整root账户另一条线是echo root:NewRootPass | sudo chpasswd。但要注意UOS出于安全默认锁定root单纯改密码不一定会解锁root登录。要解锁得sudo passwd -u root并确认/etc/ssh/sshd_config里PermitRootLogin不是no。这属于系统加固策略批量操作前要和单位安全策略对齐别乱开root权限。3.3 字体批量下发打包、落位与字体缓存刷新“统信系统怎么下载字体”是高频搜索词。国产办公场景里方正字体或单位定制字体经常需要全量下发否则办公文档排版全乱。批量装字体三步把字体文件打包、落位到字体目录、刷新字体缓存。从内网源下载的场景我一般先在控制机把字体包准备好打成tar包再批量化分发# 1. 打包字体: 字体目录里放ttf/otf文件即可 tar czf fonts.tar.gz -C ./fonts . # 2. 批量拷贝并安装 while read -r ip user port; do scp -q -P $port fonts.tar.gz ${user}${ip}:/tmp/ ssh -p $port ${user}${ip} \ sudo mkdir -p /usr/share/fonts/custom \ sudo tar xzf /tmp/fonts.tar.gz -C /usr/share/fonts/custom \ sudo fc-cache -f /usr/share/fonts/custom /dev/null \ fc-list | grep -c custom | xargs echo [OK] $HOSTNAME custom字体数量: done hosts.txt逻辑与边界字体落位在/usr/share/fonts/custom全系统可用比放~/.fonts更省事——批量脚本不用关心每个用户的家目录。fc-cache -f必须执行否则图形应用不会发现新字体这是新手最容易漏的一步。验证用fc-list | grep -c custom统计字体数量能确认缓存正常。要注意UOS有些版本WPS自带字体子集和系统字体目录是两套体系WPS场景还要看WPS的字体目录是否独立配置——这个属于应用层适配批量脚本只保证系统层字体就绪。字体下发还有一个务实的问题字体文件从哪来。单位有正版授权字体就放内网共享目录没有授权的情况下可以用系统自带的开源字体包通过apt源里的fonts-前缀包安装。批量脚本的意义在于把字体安装这件事标准化来源合规性要实施单位自己把关。4. 异常场景批量修复磁盘占满、密码锁定与登录界面进不去4.1 uos系统盘满了怎么批量清理“uos系统盘满了”是典型求助词。UOS桌面系统盘满的大头一般是三个journald日志、apt缓存、用户目录core dump。systemd-journald默认日志可能累积几个GBapt缓存也常有几百MB残留。# 磁盘占用批量体检 清理 while read -r ip user port; do ssh -p $port ${user}${ip} \ echo $HOSTNAME 根分区占用 \ df -h / | tail -1 \ echo --- journald 日志量 --- \ sudo journalctl --disk-usage | tail -1 \ sudo journalctl --vacuum-size100M /dev/null 21 \ sudo apt clean \ echo [OK] $HOSTNAME 清理完成 done hosts.txt逻辑与参数journalctl --disk-usage先看日志占多少--vacuum-size100M把journald日志压缩到100M以内apt clean清掉下载缓存。这两步是UOS上最安全也最有效的清理手段。清理完成后df -h /对比清理前后把数字留在日志里这就是批量执行的核验证据。占用大户还有~/.cache目录里面是各应用缓存。这一步要小心普通用户目录下的缓存用root清理会改变目录属主引发权限问题。批量脚本如果必须清用户缓存先确认用户目录归属或者干脆制定“只清系统日志不碰用户目录”的保守清理策略。4.2 root账户锁定与1440分钟密码锁的解除UOS用户密码连续输错会触发PAM的faillock机制默认锁定1440分钟正好24小时。这个数字写死在策略文件里手工去解要一台台找root执行命令。批量脚本的处理思路是先摘除锁再决定要不要调策略。# 批量解锁指定用户的密码锁定 while read -r ip user port; do ssh -p $port ${user}${ip} \ sudo faillock --user uosuser --reset \ echo [OK] $HOSTNAME uosuser 已解锁 || \ echo [FAIL] $HOSTNAME 解锁失败 done hosts.txt # 检查锁定策略的实际配置 grep -r unlock_time /etc/pam.d/ 2/dev/null逻辑与参数faillock --user 用户名 --reset清掉失败计数立即解除锁定不用等1440分钟走完。unlock_time在PAM配置里定义常见位置是/etc/pam.d/system-auth或登录相关文件。要不要把1440改成更短的值要看安全策略批量改策略的做法是sed -i s/unlock_time1440/unlock_time900/但这种全局改动影响面大改前必须有安全评估。现场常见的局面是用户被锁了急着重置密码但执行脚本的账号又被sudo策略限制。所以批量解锁脚本的执行账号建议是root或具备NOPASSWD sudo授权的专用账号——这需要在系统实施阶段就规划好。root账户本身被锁是另一个问题。UOS默认root锁定且无密码批量开启root要分两步走前面第3章提过。这里补一句root账户锁定状态下sudo su -会失败或者要求root密码很多实施人员误以为sudo坏了实际上是UOS的主动加固策略。4.3 登录界面进不去的批量恢复路径“统信uos家庭版21.3进不了登录界面”这类问题根源通常是三个磁盘满导致lightdm起不来、显卡驱动异常、桌面服务startdde崩溃。批量修复前先区分症状SSH能连的机器都好办# 先批量看登录服务和磁盘状态 while read -r ip user port; do ssh -p $port ${user}${ip} \ systemctl is-active lightdm; systemctl is-active startdde; df -h / | tail -1 done hosts.txt # 对lightdm异常的重启桌面服务先确认该机器无在线用户 ssh -p $port ${user}${ip} \ who | grep -q . echo [SKIP] $HOSTNAME 有活动用户 || \ sudo systemctl restart lightdm sudo systemctl restart startdde逻辑与参数systemctl is-active看两个服务状态正常是active异常是failed或inactive。lightdm是显示管理器startdde是桌面环境的进程管理服务两个都正常登录界面才能起来。磁盘满的情况必须先清理再重启服务否则重启也起不来。这里有个重要认知systemctl restart lightdm会踢掉当前所有图形会话如果机器上还有人在办公你要先确认这批机器没有在用否则就是误伤。批量重启前先扫描已登录用户有会话在线就跳过脚本里我用who | grep -q .做判断。双系统场景下win10和UOS共存进不了登录界面还要考虑GRUB引导问题。批量修复引导的做法是把update-grub放进批量队列里重生成引导菜单但GRUB菜单的默认项、超时参数需要在单台机器上先验证不能盲改。统信UOS桌面系统的安装部署阶段如果做过分区规划双系统引导顺序应该已经在装系统时定好批量脚本只做兜底修复不做重新分区这类高风险操作。5. 批量操作避坑现场五个让脚本翻车的真实案例5.1 现象并发一开就出现大量SSH连接被拒现象脚本并发设20跑到第30台机器时开始连环报ssh_exchange_identification日志里全是Connection closed by remote host。原因目标机sshd的MaxStartups限制。OpenSSH默认阈值约10个未认证连接批量脚本同时发起太多SSH握手超出阈值后直接丢弃连接。解决并发降到10以内同时给脚本加上失败重试。# 失败自动重试最多试3次间隔5秒 exec_ssh() { local ip$1 user$2 port$3 cmd$4 for i in 1 2 3; do if timeout 120 ssh -p $port ${user}${ip} $cmd; then return 0 fi sleep 5 done return 1 }重试间隔5秒错开握手的波峰。这是批量脚本里最实用的一段代码别看它简单能省掉一半的所谓“随机失败”。血泪经验凡是日志里报Connection closed的先查并发再查网络不要一上来怀疑脚本逻辑。5.2 现象chpasswd 报了成功用户还是登不进去现象脚本日志里[OK]用户却说密码不对或者输入新密码后直接闪退回登录界面。原因chpasswd执行成功只代表密码已写入shadow但目标机的用户可能属于另一套认证域比如LDAP或AD域本地shadow根本不起作用。另外UOS的keyring也就是Gnome密钥环保存着旧密码图形登录时解锁密钥环失败也会表现成登录异常。解决批量重置密码后顺带在目标机执行chage -d 0 用户名让密码立即过期要求用户下次登录强制改密避免密钥环里的旧凭据错位。如果单位接入了AD域那这套chpasswd方案根本不适用要走域控侧的重置入口。实施前的判断顺序是先确认目标机认证方式再做批量操作不要默认所有机器都是本地账户。5.3 现象字体装完重启WPS里还是看不到字体现象fc-list | grep custom有输出字体文件也在但WPS打开文档字体仍然显示缺失。原因字体缓存刷了系统层但WPS这类应用有独立的字体缓存。某些UOS版本上WPS通过/usr/share/fonts读取文件但会缓存字体列表重启应用前不会主动刷新。解决装完字体后批量删除WPS的字体缓存常见路径是~/.cache/fontconfig和WPS专属缓存目录然后让用户重启WPS。这个坑说明批量脚本验证不能只看系统侧指标要看应用真实表现。同样的逻辑也适用浏览器、LibreOffice等应用它们各有各的字体管理方式。5.4 现象磁盘清理脚本把系统清出异常现象执行清理后部分机器网络服务异常或桌面组件报错查日志发现/var/log里关键归档被删或者误删了/var/tmp下运行程序依赖的临时文件。原因清理脚本用了rm -rf写得太粗暴。/var/log下的某些子目录由软件包创建删掉后软件服务会拒绝写日志甚至起不来。解决清理动作只用机制内命令也就是journalctl和apt clean这类自带安全边界的工具不用裸rm。确需删除大文件时先du -sh列出候选人工确认白名单目录再删。给脚本加一层“只清理、不删除”的dry-run模式用--vacuum-size这类自带边界的机制兜底。这个案例的教训是批量脚本的破坏力是单台手动的100倍命令里出现rm的时候要停下来多问一句。5.5 现象同一批清单里兆芯和AMD机器脚本结果不一致现象同一条命令在AMD机器上执行成功在兆芯机器上报错或者行为不同。查证发现是BIOS固件版本或内核模块差异。原因这不算脚本bug是硬件差异。zhaoxin处理器在UOS上的驱动、BIOS设置和电源管理各有差异某些涉及CPU特性的命令行为不一致。特别是涉及lscpu输出解析、内核模块加载这类底层操作不同平台差异会被放大。解决在主机清单里加入架构列脚本执行前先探测# 探测CPU厂商用于分路执行 cpu_vendor$(lscpu | grep -o Zhaoxin\|AMD\|Intel | head -1) echo $cpu_vendor批量脚本按架构分组执行避免“一刀切”。这也是为什么主机清单不要用脚本自动扫描人工维护IP和架构信息看起来费事实际上是最可靠的数据来源。6. 让批量脚本跑得更稳幂等设计、灰度验证与回滚习惯6.1 幂等设计同一脚本跑两遍不产生副作用批量操作最怕的不是脚本出错而是“跑一半失败、修复后重跑结果把已经成功的那部分又动了一遍”。解决办法是幂等每个操作执行前先判断目标状态已满足直接跳过。展示一个带判断的字体安装片段# 字体目录已存在则跳过解包直接刷缓存 if ssh -p $port ${user}${ip} [ -d /usr/share/fonts/custom ]; then echo [SKIP] $ip 字体已安装 else scp -q -P $port fonts.tar.gz ${user}${ip}:/tmp/ ssh -p $port ${user}${ip} \ sudo mkdir -p /usr/share/fonts/custom \ sudo tar xzf /tmp/fonts.tar.gz -C /usr/share/fonts/custom \ sudo fc-cache -f /usr/share/fonts/custom fi核心逻辑就是“先查状态再执行”让脚本天然支持断点续跑。激活、密码重置同理先查激活状态已经activated就跳过重置密码前先chage查密码过期信息再决定动不动。幂等设计的额外收益是日志干净——没有一堆重复执行的噪音排错时一眼能看到哪台机器真的执行过。6.2 灰度验证先3台再30台再全部批量脚本第一次在一个环境跑强制自己走灰度先从主机清单里抽出3台不同架构的机器跑一遍逐条看日志。没问题再抽10台最后全量。这个过程看似多花了时间但它能拦住绝大多数批量事故。有一件事我吃过亏第一版脚本只在一台AMD机器上测过直接上全量结果Intel机器上的路径不一样100台里30台失败。从那以后灰度验证成了习惯而且灰度批次必须覆盖架构差异、系统版本差异和网络分段差异。统信UOS桌面系统的安装部署阶段如果有测试机先把批量脚本在测试机上完整跑一遍再进生产环境这个顺序不能省。6.3 执行前快照与回滚清单给自己留后悔药批量操作的后悔药不是备份镜像而是执行前的状态快照加回滚命令清单。跑任何批量改动前先批量收集目标状态到本地存档格式简单几行脚本就能完成# 执行前快照: 关键改动项的原始状态 while read -r ip user port; do ssh -p $port ${user}${ip} \ echo 磁盘 df -h / | tail -1 \ echo 密码策略 sudo grep unlock_time /etc/pam.d/* 2/dev/null \ echo 激活状态 uos-activation --status 2/dev/null \ snapshot_${ip}.txt done hosts.txt这些快照文件既是验证脚本是否生效的基线也是出问题时的排错入口。真出了意外回滚的原则是先恢复策略类配置再动用户数据。快照文件按日期归档和logs目录放在一起形成一个完整的执行档案。我自己养成的习惯是每次批量执行的文件名带上执行批次和日期没跑完就永远不删logs目录。这个习惯救过我很多次——下个季度有台机器出问题翻回当时的执行日志五分钟就能定位是不是批量脚本留下的副作用。批量脚本这件事真正的门槛不在写命令而在“能不能安全地试错”。把灰度、快照、幂等这三件事焊死在脚本里UOS批量操作就从赶工变成可控工程。希望帮到你。本文还有配套的精品资源点击获取
返回列表