多台机器时,简便的一条命令多台执行的方式

本文介绍在互联网企业中如何利用SSH实现跨多台机器的批量操作,包括原理介绍及实际应用场景,如日志查询和内存使用情况检查等。

1.简介


         在互联网企业,现在分布式几乎是必备,我们同一个业务线上的机器一般是大于1台。在这种情况下,我们经常遇到这么一个场景,为了排查一个问题,我们需要上多台机器上多次执行同一条命令,来查询日志,或者查询内存使用情况。现在可以对这个场景进行简化,在一台机器上配置ssh访问另外多台台机器,在这一台机器上执行命令,同时可以获取其他机器的结果。

         


2.ssh原理与运用


         

2.1.ssh原理


         ssh登录被认为是一种的安全的登录方式,不同于明文密码登录,ssh使用公钥加密密码,登录时使用加密后的密码,远程主机收到后,使用私钥解密,拿到登录密码,如果密码正确,就同意此次登录。

         

2.2.ssh运用

         
         

3.拓展与总结


         

3.1拓展


         

3.2总结

         
         
         
<think>好的,我现在需要帮用户解决如何编写一个shell脚本,在30台远程主机上并发执行多条命令的问题。用户提到了并发执行,所以首先我得考虑如何实现并发操作,同还要处理远程主机的连接和命令执行。 首先,用户的需求是在30台机器上同运行多条命令,可能需要用到并行处理的方法。常见的工具有ssh、ansible或者pssh,但用户可能希望用纯shell脚本实现,或者结合一些简单的工具。根据用户提供的引用,特别是引用[1]中的三种方法,比如使用for循环结合&后台执行,或者用xargs,或者用sshpass处理密码的情况。还有引用[2]提到ansible的script模块,可以执行本地脚本到远程主机,但用户这里可能更倾向于自己编写脚本而不是使用ansible。 首先,我需要考虑如何在不使用ansible的情况下,用shell脚本来实现。比如,使用ssh连接到每台主机,并在后台运行这些命令。这里需要注意几点:如何管理主机的IP列表,如何处理ssh的认证(比如使用密钥认证还是密码),以及如何控制并发数,避免同启动太多进程导致资源耗尽。 用户可能需要一个脚本,读取主机列表,然后对每个主机执行ssh命令,并在后台运行。例如,使用一个循环遍历所有主机,每个ssh连接放在后台,使用&符号,然后使用wait来等待所有后台任务完成。不过这样可能会同启动30个进程,如果主机数量多的话可能会对本地机器造成压力,所以可能需要对并发数进行限制,比如每次只并发5个或者10个。 另外,引用[1]中提到多节点并发执行的三种方法,其中第二种是使用xargs的-P参数控制并发数。这可能是一个有效的方法,可以结合ssh命令和xargs来实现并发执行。 然后,关于执行多条命令,用户可能需要在一个ssh会话中执行多个命令,可以通过将命令用分号连接,或者使用heredoc的方式输入。例如,ssh user@host "command1; command2; command3"。 接下来,需要处理主机的认证问题。如果已经配置了ssh免密登录,那么脚本可以更简单,否则可能需要使用sshpass来传递密码,但这样不太安全。建议用户配置ssh密钥认证,这样脚本中就不需要处理密码的问题。 结合这些点,脚本的大致思路可能是: 1. 准备一个主机列表文件,比如hosts.txt,每行一个主机IP或主机名。 2. 读取该文件,对每个主机执行ssh命令,发送需要执行命令。 3. 使用xargs或者循环结合后台进程来并发执行。 4. 控制并发数,避免同过多进程。 例如,使用xargs的-P参数指定并发数,如-P 5表示同处理5台主机。然后结合ssh命令执行。 另外,用户可能需要执行多条命令,可以将这些命令写成一个脚本,或者通过ssh直接传递多条命令。例如: ssh user@host <<EOF command1 command2 EOF 这样可以将多行命令传递给远程主机执行。 综合这些考虑,可以提供一个使用parallel-ssh工具(如pssh)的解决方案,或者使用纯bash脚本结合xargs的方法。不过用户可能希望用最基本的工具,所以可能会选择后者。 另外,引用[3]中的例子提到了写入文件到远程主机,可能需要类似的步骤,比如将命令写入脚本,然后分发执行,但用户的问题更偏向于直接执行命令而不是分发脚本。 现在需要检查用户提供的引用,尤其是引用[2]中的ansible示例,但用户可能不想使用ansible,而是用shell脚本。因此,可能需要编写一个bash脚本,使用循环和后台进程。 可能的脚本结构: - 读取主机列表 - 定义要执行命令 - 对每个主机,启动后台进程执行ssh命令 - 等待所有进程完成 但如何控制并发数?比如,每次启动最多N个进程,然后等待部分完成后再启动新的。 例如,使用一个计数器,循环中每次启动一个后台进程,计数器加1,当计数器达到并发数,使用wait等待任意一个进程完成,再继续。 不过这可能比较复杂。另一种方法是使用GNU parallel工具,或者xargs的-P参数。 例如,使用xargs: cat hosts.txt | xargs -I{} -P 5 ssh user@{} "command1; command2" 这样可以并发5个进程,每个进程处理一个主机。但需要确保ssh命令正确,且每个主机的命令正确。 如果用户没有安装parallel,可能更倾向于使用xargs。 总结可能的步骤: 1. 创建主机列表文件hosts.txt,每行一个主机。 2. 编写脚本,读取该文件,使用xargs或循环启动并发ssh进程。 3. 处理命令的传递,可能需要将多条命令合并为一个字符串。 例如,脚本内容: #!/bin/bash # 主机列表文件 HOSTS_FILE="hosts.txt" # 并发数 CONCURRENCY=5 # 要执行命令,用分号分隔 COMMANDS="uname -a; date; hostname" # 使用xargs并发执行 cat $HOSTS_FILE | xargs -I{} -P $CONCURRENCY sh -c "echo 'Executing on {}'; ssh user@{} \"$COMMANDS\"" 但需要注意,如果命令中有特殊字符,可能需要转义处理。此外,ssh命令需要配置免密登录,否则会提示输入密码。 如果用户没有配置免密登录,可能需要使用sshpass,但这样会暴露密码,不建议。 另外,如果命令中存在引号或者变量,可能需要更复杂的处理,比如使用heredoc。 或者,可以将命令写入一个脚本文件,然后使用scp复制到远程主机,再执行,但这样步骤更多。 如果用户希望直接在远程执行多条命令,可以将命令放在引号中,用分号分隔,或者使用单引号包裹。 例如: COMMANDS='uname -a; date; hostname' 然后在ssh命令中使用双引号包裹: ssh user@{} "$COMMANDS" 或者,如果命令中有变量,需要转义处理。 另一种方法是使用脚本内的函数来处理每个主机的命令,然后在后台执行。 例如: #!/bin/bash execute_commands() { host=$1 echo "Executing on $host" ssh user@$host <<'EOF' command1 command2 command3 EOF } export -f execute_commands cat hosts.txt | xargs -I{} -P 5 bash -c 'execute_commands "$@"' _ {} 这样,使用heredoc传递多行命令,并且通过xargs并发处理。但需要导出函数,并且可能在不同的shell中运行。 不过这可能比较复杂,用户可能更倾向于简单的方法。 综上,最终的脚本可能是一个结合xargs和ssh的简单脚本,控制并发数,并执行多条命令。同建议用户配置ssh免密登录,避免密码输入的问题。 现在需要考虑示例中的代码是否正确,比如是否正确处理并发和多命令,以及如何引用用户提供的参考内容。 用户引用中的引用[1]提到三种方法,其中第三种是使用sshpass,但可能不安全。用户引用中的方法可能更偏向于使用简单的shell脚本实现并发,而不是使用ansible等工具。 因此,回答中需要给出使用shell脚本的方法,可能包括使用for循环结合后台进程,或者xargs控制并发,并处理多条命令。同,可以提到ansible作为替代方案,但用户的问题是关于shell脚本的。 另外,用户可能希望脚本能够处理错误,比如某些主机连接失败的情况,但问题中没有特别说明,所以可能不需要处理。 最后,需要生成相关问题,比如如何配置ssh免密登录,如何限制并发数,如何处理命令中的特殊字符等。</think>### 分步解决方案 #### 1. 准备主机列表文件 创建名为 `hosts.txt` 的文本文件,每行写入一个远程主机的IP地址或主机名: ``` 192.168.1.101 192.168.1.102 ... ``` #### 2. 配置SSH免密登录(关键步骤) 在所有远程主机上配置SSH密钥认证,避免手动输入密码[^1]: ```bash # 本地生成密钥对(若未生成过) ssh-keygen # 将公钥分发到所有远程主机 while read host; do ssh-copy-id user@$host; done < hosts.txt ``` #### 3. 编写并发执行脚本 使用 `xargs` 控制并发数(例如并发5台),通过SSH执行多条命令: ```bash #!/bin/bash # 定义变量 HOSTS_FILE="hosts.txt" CONCURRENCY=5 # 并发数量 USER="your_username" COMMANDS=( "date" # 示例命令1:查看间 "uname -a" # 示例命令2:查看系统信息 "df -h /" # 示例命令3:查看磁盘使用 ) # 拼接命令为单行字符串 CMD_STRING=$(IFS=';'; echo "${COMMANDS[*]}") # 并发执行 cat $HOSTS_FILE | xargs -I{} -P $CONCURRENCY \ sh -c "echo '==== {} ===='; ssh $USER@{} \"$CMD_STRING\"" ``` #### 4. 高级用法 - **错误重定向**:添加 `2>&1` 到ssh命令后记录错误 - **超控制**:添加 `-o ConnectTimeout=10` 限制连接超间 - **结果保存**:重定向输出到文件(`>> output.log 2>&1`) --- ### 替代方案对比 | 方法 | 优点 | 缺点 | |---------------|-------------------------|-----------------------| | Shell+xargs | 无需额外工具 | 并发控制较基础 | | Ansible | 自带错误处理/结果收集 | 需要安装/学习成本 | | pssh工具 | 专业远程批量执行 | 需额外安装 | --- ### 注意事项 1. **网络稳定性**:建议添加SSH参数 `-o ServerAliveInterval=60` 2. **敏感操作**:避免在远程执行 `rm -rf /` 等危险命令 3. **输出混淆**:建议为每台主机的输出添加主机名标识
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值