到目前为止,我找到了一个令人满意的解决方案,但想知道是否有一种方法可以使用更多并行的设计选项。
我正在跑步
parallel --version
20240422.
我已阅读
man parallel
和https://www.gnu.org/software/parallel/parallel_tutorial.html和这本书,但没有一个示例符合我的具体要求
环境已经导出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
选项会将后面的任何参数解释为端口号和错误。一定有更好的方法。
总结
反馈
GNU 并行通常工作得很好,特别是使用
--dry-run
和 --joblog
来帮助调试,但对于文档未涵盖的此类情况,考虑到有如此多的选项,添加调试/贡献指南将为用户提供帮助交互,以及多种指定服务器或接受输入的方法。
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 修复。