Linux环境下多服务器批量操作脚本的配置文件编写方法咨询
嘿,我来帮你把这两个问题理清楚,顺便调整下脚本的小问题~
关于Host字段的名称
你在Host后面填写的是自定义的服务器别名,只要是你能区分的名称就行,比如jenkins-prod、build-node-02这种有意义的名字。这个别名的作用是让你可以直接用ssh 别名来连接服务器,不用每次输入user@hostname,而且SSH会自动加载该别名对应的所有配置(比如IdentityFile、ServerAliveInterval这些)。
举个正确的配置示例:
Host jenkins-prod Hostname xyz.example.com User user1 IdentityFile /path/to/your.pem ServerAliveInterval 220 Host build-node-02 Hostname lmn.example.com User user2 IdentityFile /path/to/another.pem ServerAliveInterval 220
编写服务器列表配置文件的所有可行方法
根据你的需求(安全、易解析),推荐以下几种方案:
方法1:SSH原生配置文件(最推荐)
就是你现在尝试的这种格式,它是SSH官方支持的配置文件,默认路径是~/.ssh/config,也可以单独写一个自定义文件(比如你手里的hosts_config)。
- 优势:无需自己写解析逻辑,SSH直接识别所有参数,支持SSH的全部配置项(端口、代理、密钥等),安全性高(可以给配置文件设置
chmod 600权限,避免其他人读取)。 - 使用方式:脚本中用
ssh -F ./hosts_config 别名指定配置文件连接。
方法2:键值对/INI格式配置文件
适合需要自己在脚本中解析参数的场景,结构清晰,容易用bash/awk处理:
[jenkins-prod] hostname = xyz.example.com user = user1 pem_path = /path/to/your.pem server_alive_interval = 220 [build-node-02] hostname = lmn.example.com user = user2 pem_path = /path/to/another.pem server_alive_interval = 220
或者更简洁的单行分隔格式(用空格或逗号分隔):
jenkins-prod xyz.example.com user1 /path/to/your.pem 220 build-node-02 lmn.example.com user2 /path/to/another.pem 220
脚本中可以用while read循环直接读取每行的参数:
while read alias hostname user pem interval; do # 执行连接和数据提取逻辑 done < ./hosts_list.txt
方法3:JSON/YAML结构化配置文件
如果你的服务器配置有复杂的分组、额外参数(比如端口、备注),可以用结构化格式,适合用Python/Go等语言解析:
JSON示例:
[ { "alias": "jenkins-prod", "hostname": "xyz.example.com", "user": "user1", "identity_file": "/path/to/your.pem", "server_alive_interval": 220 }, { "alias": "build-node-02", "hostname": "lmn.example.com", "user": "user2", "identity_file": "/path/to/another.pem", "server_alive_interval": 220 } ]
YAML示例:
servers: - alias: jenkins-prod hostname: xyz.example.com user: user1 identity_file: /path/to/your.pem server_alive_interval: 220 - alias: build-node-02 hostname: lmn.example.com user: user2 identity_file: /path/to/another.pem server_alive_interval: 220
这种格式的优势是扩展性强,适合复杂场景,但需要用专门的库来解析(比如Python的json/pyyaml模块)。
修正你当前的脚本
你现在的脚本有几个语法和逻辑问题,比如source ./hosts_config无法正确解析SSH配置文件,while read的写法错误,ssh的判断逻辑不对。这里给你一个基于SSH配置文件的修正版:
#!/bin/bash # 指定自定义SSH配置文件路径 SSH_CONFIG="./hosts_config" # 提取配置文件中所有的服务器别名(排除通配符Host *) host_aliases=$(awk '/^Host / && $2 != "*" {print $2}' "$SSH_CONFIG") # 循环每个服务器别名 for alias in $host_aliases; do # 尝试连接服务器,静默输出 if ssh -F "$SSH_CONFIG" "$alias" "echo 'Connected successfully'" > /dev/null 2>&1; then echo "✅ Successfully logged into $alias" # 这里添加你的数据提取逻辑,比如从远程文件读取内容保存到本地: ssh -F "$SSH_CONFIG" "$alias" "cat /path/to/remote/target_file" >> ./local_extracted_data.txt else echo "❌ Failed to login to $alias" fi done
这个脚本会自动读取你的hosts_config中的所有服务器别名,依次尝试连接,成功后提取数据到本地文件。
内容的提问来源于stack exchange,提问作者Gourav Saini

