我尝试编写一个 shell 脚本,通过 登录多个主机ssh
,执行一些命令,并打印执行摘要。到目前为止,我已经编写了一个可以在顺序的方式。但是很慢,我想以并行的方式重写它。我知道我可以用来&
并行运行多个 ssh 命令,并使用“命令替换”将subshell
输出存储到变量中。但我无法正确地将它们组合起来。
到目前为止,我已经输出了这些代码。但它仍然按顺序运行。
#!/bin/bash
hosts=( 'host-1' 'host-2' 'host-3' )
cmd='sleep $[ (( $RANDOM % 20 ) + 1) /10 ]s && echo hello world'
i=0
for host in ${hosts[@]}; do
var1=$(ssh $host $cmd &)
echo "i = $i"
outputs[i]="$var1"
((i++))
done
echo 'wait'
wait
echo ${outputs[@]}
答案1
我认为您不能在后台有效地使用变量分配(无论是否使用命令替换),因为后台作业在子 shell 中运行。例如
foo=x
foo=$(echo y) &
echo "$foo"
将打印x
第二个分配仅适用于子 shell。
另一方面,在命令替换内部后台运行也不会执行您想要的操作,shell 无论如何都会等待命令,并且您会按顺序执行任务:
sleepecho() { sleep "$1"; echo "$2"; }
foo=$( sleepecho 5 abc & ) # returns after five seconds
echo "$foo" # prints 'abc'
您可以做的是将命令的输出存储在临时文件中。这将使背景工作,并且如果输出很长也可能更好。
dir=$(mktemp -d)
for h in "${hosts[@]}" ; do
ssh "$h" "$cmd" > "$dir/$h" &
done
wait
do something with "$dir/"*
尽管有许多现成的解决方案可以通过ssh
...在多个主机上运行命令