如何使用gnu并行使用sshpass在多个服务器上运行相同的命令?

问题描述 投票:0回答:1

到目前为止,我找到了一个令人满意的解决方案,但想知道是否有一种方法可以使用更多并行的设计选项。

我正在跑步

parallel --version
20240422.

我已阅读

man parallel
https://www.gnu.org/software/parallel/parallel_tutorial.html和这本书,但没有一个示例符合我的具体要求

  1. 密码身份验证(最好使用 sshpass),而不是公钥/私钥
  2. 允许将服务器列表保存在文件中(因此可以轻松编辑)
  3. 服务器有不同的端口,有些默认22,有些则没有

环境已经导出SSHPASS。

我尝试了很多方法,但不确定这是语法问题还是环境设置(并行不继承SSHPASS的实例(子shell?))问题。

要先检查命令和环境的正确性而无需并行,

sshpass -e ssh <user>:@<ip> -p <port>
有效。


Quirk:我在

:
之后添加
user
作为适应 gnuparallel 的解决方法,因为

  • parallel -S <user>@<ip>:<port> echo ::: 1
    不起作用
  • parallel -S <user>:@<ip>:<port> echo ::: 1
    有效。

我不知道为什么 gnu-parallel 需要这个

:
,但我将它添加到从这里开始的所有实验中,即使它可能被过度指定。 关于如何调试有什么建议吗?我安装了 gnu 并行 perl 源代码和 VSCode Perl 语言服务器,但由于某些语言服务器错误,调试器提前停止在
sub parse_options()
中。其他人也想:有没有办法调试 GNU Parallel?


因为

sshpass -e ssh <user>:@<ip> -p <port>
有效,我希望如果使用文件
parallel --slf iplist  echo ::: env
来存储包含不同 ip 和端口的所有服务器,
iplist
也能工作

sshpass -e ssh <user>:@<ip1> -p <port1>
sshpass -e ssh <user>:@<ip2> -p <port2>

每一行都是 gnu 并行词汇中的

sshlogin
,格式为
[sshcommand [options]] [username[:password]@]hostname
来自
man parallel

输出

2 行

parallel: Warning: Could not figure out number of cpus on sshpass -e ssh <user>:@<ip> -p <port> (). Using 1.
,然后说
Permission denied, please try again

将并行更改为 env_parallel

最后一个错误通常发生在您在 ssh 中输入错误密码或空密码时。 然后我想从并行启动的实例中是否缺少 SSHPASS,也是如此

env_parallel --env SSHPASS --slf iplist  echo ::: env
查看与上一个命令完全相同的错误。

我没有尝试使用

-S
语法,因为当你有多个服务器时这是不切实际的

保持简单

我决定停止依赖像

--ssh
--slf
-S
这样的任何选项,因为我不知道它们在幕后做什么(被前面提到的调试器阻止),并放在一个命令中,尽可能多的所需信息。

iplist 包含

<user>:@<ip1>
<user>:@<ip2>

现在这部分有效了。 (如果使用

parallel
,则给出 2x
Permission denied, please try again.

cat iplist | env_parallel  --env SSHPASS sshpass -e "ssh {} -p <port>  'env;hostname'"

无法更改端口!

因为有些服务器默认为22,所以我不想在命令中进行硬编码,而是将其放入

iplist
文件中,如
<user>:@<ip2> -p <port>
,以使用
cat iplist | env_parallel --env SSHPASS sshpass -e "ssh {} 'env;hostname'"
进行调用 现在我明白了
hostname contains invalid characters

--dry-run
向我展示了
sshpass -e ssh '<user>:@<ip> -p <port>' 'env;hostname'
,在没有并行的情况下单独运行时会给出相同的错误(我这样做是作为额外检查)。我在 iplist 中所做的其他引用尝试都无法解决此错误。

看起来已经解决了,但是还能更好吗?

然后我注意到

--colsep
可以将输入解释为表格和
cat iplist | env_parallel --colsep ' ' --env SSHPASS "sshpass -e ssh {1} -p {2} 'env;hostname'" > results.txt
有效。

ip列表包含

ip1 port1
ip2 port2

这个 --colsep 使我免于使用 awk 进行逆旋转

awk '{printf "%s\n%s\n", $1, $2}' iplist | env_parallel <truncated>

ip1
port1
ip2
port2

,然后使用并行的

-N2
一次读取 2 行,并分别使用替换字符串 {1} {2} 引用 ip、端口。

我仍然必须在 iplist 中对没有非默认端口的 ip 进行硬编码 22,而不是忽略它,否则它要么会破坏此结构,要么

ssh -p
选项会将后面的任何参数解释为端口号和错误。一定有更好的方法。

总结

  1. 我想使用设计的选项以获得可能的语法便利,但不知道它们的影响或交互
  2. 我想调试并行 Perl 脚本以了解选项的作用(尤其是 --onall 引发了另一个问题gnu parallel 的 --onall 不适用于 sshpass 吗?

反馈

GNU 并行通常工作得很好,特别是使用

--dry-run
--joblog
来帮助调试,但对于文档未涵盖的此类情况,考虑到有如此多的选项,添加调试/贡献指南将为用户提供帮助交互,以及多种指定服务器或接受输入的方法。

gnu-parallel
1个回答
0
投票

SSH 登录,例如:

user@host

将运行

ssh -l user host

user:@host

将运行

sshpass -e ssh -l user host

:@host

将运行

sshpass -e ssh host

user:mypass@host

将运行

SSHPASS=mypass sshpass -e ssh -l user host

因此,在用户后面需要额外的 ':' 的原因是告诉 GNU Parallel 将

sshpass
与运行 GNU Parallel 之前设置的
$SSHPASS
一起使用。

您可以将

:<port>
添加到
host
来设置端口(如您所期望的)。

所以这些在

myslf

user:@host
:@host:2222
user:pass@host:22223

但是您似乎发现了一个错误:

user:pass@host
不适用于
--onall

此问题将于 20240522 修复。

© www.soinside.com 2019 - 2024. All rights reserved.