GNU Parallel --onall与sshpass兼容问题及多服务器执行命令求助
使用GNU Parallel在密码认证服务器批量执行命令的问题与解决
场景复现
我尝试在多台采用密码认证的服务器上执行相同命令,已导出SSHPASS环境变量,但添加--onall选项后出现执行失败的情况,具体测试如下:
- 场景1:执行
parallel -S 1/user:@ip echo ::: foo成功输出foo(似乎自动调用sshpass,且用户后必须加冒号否则会无限挂起,原因未知) - 场景2:执行
parallel -S 1/user:@ip,1/user:@ip2 --onall echo ::: foo时终端无响应并挂起 - 场景3:执行
parallel --ssh "sshpass -e ssh" -S 1/user:@ip,1/user:@ip2 --onall echo ::: foo时,返回两次Permission denied, please try again.(和手动输错密码执行ssh user@ip的错误一致,推测--onall导致未发送正确密码) - 场景4:执行
parallel --ssh "sshpass -e ssh" --slf iplist --onall echo ::: foo时,输出与场景3相同(iplist是场景2、3中IP的换行分隔列表,推测--slf与-S功能一致)
问题
- 如何在需密码认证的多台服务器上执行相同命令?
- 为何
--onall会导致终端无响应挂起?后台是否存在交互等待?
解决方法与原因分析
1. 密码认证服务器批量执行命令的正确方式
核心是确保sshpass能正确传递密码,同时规范parallel的参数格式:
- 明确指定ssh命令:必须告诉
parallel使用sshpass -e ssh作为ssh客户端,避免默认原生ssh触发交互式密码输入。 - 规范服务器地址格式:服务器地址用
user@ip的标准格式,不要加多余的1/或冒号。- 用
--slf加载服务器列表文件时,iplist每行格式应为user@ip,执行命令:parallel --ssh 'sshpass -e ssh' --slf iplist --onall echo foo - 直接用
-S指定服务器时,执行命令:parallel --ssh 'sshpass -e ssh' -S user@ip,user@ip2 --onall echo foo
- 用
2. --onall导致异常的原因
- 终端无响应挂起(场景2):未指定
--ssh参数时,parallel默认调用原生ssh,而ssh会后台等待交互式输入密码,但终端被parallel接管后没有显示密码输入提示,所以看起来是无响应挂起。 - 认证失败(场景3、4):服务器地址格式错误(多余的
1/和冒号)导致sshpass无法正确解析目标主机,密码传递逻辑失效,因此出现密码错误提示;同时--onall会让每个服务器执行所有任务,格式错误进一步干扰了ssh的认证流程。
内容的提问来源于stack exchange,提问作者Han Qi
相关产品推荐
相关产品推荐

