在 Linux / Unix 集群运维语境中,dsh通常指Distributed Shell(分布式 Shell),用于在多台远程主机上同时执行相同的命令。下面从安装、配置、使用、原理、对比等方面进行系统介绍。
一、什么是 dsh
dsh是一个轻量级命令行工具,用于在多台服务器上并行执行同一个 Shell 命令,并将结果收集回本地显示。它非常适合批量查看状态、批量执行脚本、批量重启服务等场景。
例如你有 30 台 Web 服务器,想同时查看每台机器的磁盘使用率,不需要逐台 SSH 登录,只需要:
dsh -c -g web 'df -h'dsh会并发连接web组中的所有主机,执行df -h,并在每行输出前加上主机名。
二、dsh 的核心能力
批量执行命令:一条命令同时下发到多台机器。
机器分组管理:通过文件定义机器组,如
web、db、cache。并发控制:可设置最大并发连接数,避免连接风暴。
输出整理:配合
dshbak可以按主机或按输出内容分组展示。无 Agent:不依赖目标机器安装额外服务,仅依赖 SSH/Rsh。
配置简单:纯文本配置,容易理解和管理。
三、安装
Debian / Ubuntu
sudo apt update sudo apt install -y dshCentOS / RHEL
部分发行版默认仓库可能没有dsh,可以通过 EPEL 尝试安装,或从源码编译:
# 尝试 sudo yum install dsh # 或从源码编译安装 wget http://www.netfort.gr.jp/~dancer/software/dsh.tar.gz tar xzf dsh.tar.gz cd dsh-* ./configure make sudo make install安装完成后会包含dsh、dcs、dshbak等命令。
四、快速上手
1. 配置 SSH 免密登录
dsh通常使用 SSH 连接远程主机,因此需要提前配置 SSH 密钥认证:
ssh-keygen -t rsa ssh-copy-id user@web01 ssh-copy-id user@web02如果使用默认远程 Shell 是rsh,需要修改为ssh,否则会走不安全的 RSH 协议。
2. 创建机器组
mkdir -p ~/.dsh/group cat > ~/.dsh/group/web <<EOF web01 web02 web03 EOF3. 配置 dsh 使用 SSH
编辑用户级配置文件:
cat > ~/.dsh/dsh.conf <<EOF remoteshell = ssh showmachinenames = 1 forklimit = 32 EOF4. 执行第一条命令
dsh -c -g web 'uptime'输出类似:
web01: 14:00:01 up 10 days, 2:15, 1 user, load average: 0.00, 0.01, 0.05 web02: 14:00:01 up 10 days, 3:10, 2 users, load average: 0.02, 0.03, 0.05 web03: 14:00:01 up 8 days, 1:30, 1 user, load average: 0.10, 0.08, 0.06
五、配置文件详解
5.1 dsh 主配置文件
dsh的配置分为全局配置和用户配置:
全局配置:
/etc/dsh/dsh.conf用户配置:
~/.dsh/dsh.conf
常见配置项:
| 配置项 | 示例 | 说明 |
|---|---|---|
remoteshell | remoteshell = ssh | 指定远程 Shell,强烈建议使用ssh |
showmachinenames | showmachinenames = 1 | 输出时是否显示主机名,1 为显示 |
forklimit | forklimit = 32 | 最大并发连接数 |
waiter | waiter = 1 | 等待远程命令执行完成 |
shell | shell = /bin/bash | 本地使用的 Shell |
完整示例:
# ~/.dsh/dsh.conf remoteshell = ssh showmachinenames = 1 forklimit = 325.2 机器列表文件
dsh可以维护一个默认机器列表,文件位置:
全局:
/etc/dsh/machines.list用户:
~/.dsh/machines.list
每行一个主机名:
web01 web02 db01 db02
也可以使用user@host形式:
admin@web01 admin@web02
5.3 机器组
机器组文件存放在:
全局组目录:
/etc/dsh/group/用户组目录:
~/.dsh/group/
一个组名对应一个文件,文件名就是组名。例如创建 Web 组:
mkdir -p ~/.dsh/group cat > ~/.dsh/group/web <<EOF web01 web02 web03 EOF创建数据库组:
cat > ~/.dsh/group/db <<EOF db01 db02 EOF列出当前所有可用组:
dsh -M六、常用命令选项
| 选项 | 说明 |
|---|---|
-c, --concurrent | 并发执行,默认可能为顺序执行,建议加上 |
-m, --machines | 指定机器列表,逗号分隔,如-m web01,web02 |
-g, --group | 指定机器组,如-g web |
-r, --remoteshell | 临时指定远程 Shell,如-r ssh |
-f, --forklimit | 限制并发连接数,如-f 20 |
-i, --ignore-failed | 忽略连接失败的主机 |
-v, --verbose | 显示详细执行信息 |
-M, --list-groups | 列出所有机器组 |
-o, --output-file | 将输出写入指定文件 |
-s, --sort | 输出按主机名排序 |
-- | 分隔选项与命令,防止命令被误解析 |
示例:
# 指定机器列表并发执行 dsh -c -m 'web01,web02,db01' 'hostname' # 指定组并限制并发为 10 dsh -c -f 10 -g web 'systemctl status nginx' # 输出到文件 dsh -c -g web 'df -h' -o /tmp/disk_report.txt七、使用 dshbak 整理输出
dshbak是dsh配套的输出格式化工具,可以将多主机输出进行分组或合并。
按主机分组
dsh -c -g web 'uname -r' | dshbak合并相同输出
如果多台主机输出完全相同,可以使用-c合并:
dsh -c -g web 'uname -r' | dshbak -c输出类似:
---------------- 5.15.0-101-generic ---------------- web01, web02, web03
这样在集群环境一致时,阅读非常方便。
八、实战示例
1. 查看所有 Web 服务器的负载
dsh -c -g web 'uptime'2. 批量查看内存使用情况
dsh -c -g web 'free -h'3. 批量检查服务状态
dsh -c -g web 'systemctl is-active nginx'4. 批量更新软件包
dsh -c -g web 'sudo apt-get update && sudo apt-get upgrade -y'5. 批量查看磁盘使用并合并相同结果
dsh -c -g web 'df -h | grep /$' | dshbak -c6. 批量执行本地脚本
先将脚本分发到目标机器,再通过dsh执行:
dsh -c -g web 'bash /tmp/check_env.sh'7. 命令中包含管道或重定向
必须用引号将完整命令传给远程 Shell:
dsh -c -g web 'ps aux | grep nginx | wc -l'九、工作原理
dsh本质是一个“命令广播器”,其工作流程大致如下:
读取配置文件,确定远程 Shell 类型,例如
ssh。读取
-m指定的主机列表,或-g指定组文件中的主机列表。如果启用了
-c并发模式,则对每个主机创建一个子进程。每个子进程调用远程 Shell 执行命令,例如:
ssh web01 "uptime" ssh web02 "uptime"
捕获每个子进程的标准输出和标准错误。
根据配置决定是否在每行输出前添加主机名前缀。
主进程等待所有子进程结束,汇总退出状态。
因此,dsh不需要在目标机器上安装任何 Agent,只依赖 SSH/Rsh 即可完成批量操作。
十、与同类工具对比
| 工具 | 特点 | 适用场景 |
|---|---|---|
dsh | 轻量、配置简单、分组方便 | 快速批量执行命令 |
pdsh | 支持多种远程模块,HPC 常用 | 大规模集群、高性能计算环境 |
pssh | Python 实现,附带pscp、prsync等 | 批量命令 + 文件分发 |
Ansible | 无 Agent、模块化、幂等、Playbook | 配置管理、复杂自动化流程 |
ClusterSSH | 打开多个终端窗口,交互式操作 | 需要同时操作多台机器的交互场景 |
dsh的优势在于简单直接,适合日常运维中“只想快速在多台机器上跑一条命令”的场景;如果要做复杂配置管理,建议使用 Ansible。
十一、最佳实践与注意事项
务必使用 SSH 并配置密钥认证
dsh默认可能使用rsh,既不安全也不方便。配置remoteshell = ssh并完成免密登录。控制并发数
大量主机同时 SSH 连接可能造成本地端口耗尽或远程 SSH 服务压力过大。建议设置forklimit = 32或更小。先用小范围测试危险命令
批量重启、删除、更新等操作前,先对 1~2 台机器执行,确认无误后再扩大范围。注意本地 Shell 变量展开
如果命令中包含$、反引号、管道等,使用单引号包裹,防止在本地被展开。例如:dsh -c -g web 'echo $HOSTNAME'如果使用双引号,本地 Shell 会先展开
$HOSTNAME,导致所有机器输出本地主机名。使用
dshbak提升可读性
当输出量很大时,使用dshbak -c合并相同结果,快速发现异常机器。保留操作日志
重要操作可以重定向输出到文件:dsh -c -g web 'df -h' | tee /tmp/dsh_$(date +%F).log注意交互式命令不可用
dsh适合执行非交互式命令。像vim、top这类交互式命令无法正常使用,需要交互式场景请使用ClusterSSH。
十二、常见问题
1. 提示Host key verification failed
原因是首次连接远程主机时 SSH 需要确认主机指纹。解决方法是提前手动连接一次,或使用ssh-keyscan添加:
ssh-keyscan web01 >> ~/.ssh/known_hosts2. 输出没有主机名
检查配置文件是否包含:
showmachinenames = 1
3. 配置不生效
注意区分全局配置/etc/dsh/dsh.conf和用户配置~/.dsh/dsh.conf。用户配置优先级更高,检查文件语法是否正确。
4. 找不到机器组
使用dsh -M查看是否识别到组,确认组文件放在~/.dsh/group/或/etc/dsh/group/下,且文件名与组名一致。
5. 并发执行时输出混乱
这是正常现象,可添加-s排序,或使用dshbak整理:
dsh -c -g web 'df -h' | dshbak总结
dsh是一个经典的分布式 Shell 工具,核心价值在于简单、快速、轻量。通过 SSH 和简单的文本配置,就能实现在多台服务器上批量执行命令。虽然今天有 Ansible 等更强大的自动化工具,但在临时排查、批量查看状态、快速执行脚本等场景中,dsh仍然是一个非常实用的小工具。