我正在远程主机上并行运行一些查询命令,xargs
这些命令运行高效且非常好,但是在查找从哪个主机获取查询时遇到了一些问题。
现在,执行此操作的脚本部分看起来正是这样的:
export commands="cmd1; cmd2; "
hosts=("host1" "host2" "host3" "host4")
MaxInstance=10
echo_var(){
echo "Executing in $1:"; sleep 1; echo "Output of: $commands"; return 0;
}
export -f echo_var
printf "%s\n" ${hosts[@]} | xargs -n 2 -P $MaxInstance -I {} $(command -v bash) -c 'echo_var "$1"' _ {}
输出结果应类似如下,因为sleep 1
:
Executing in host1:
Executing in host2:
Executing in host3:
Executing in host4:
Output of: cmd1; cmd2;
Output of: cmd1; cmd2;
Output of: cmd1; cmd2;
Output of: cmd1; cmd2;
为了实现与最后显示的输出类似的输出,我必须将现有函数编辑为以下内容以更接近我想要的。但即使在这里我使用printf "%s\n%s" "$name" "$output"
,它有时也会在新行处中断。例如:
echo_var(){
name="Executing in $1:"; sleep 1; output="Output of: $commands";
echo -e "$name: $output" ## will work
# echo -e "$name\n$output" ## will not work or even
# printf "%s\n%s" "$name" "$output" ## will not work
return 0;
}
在不牺牲并行执行速度的情况下,我希望得到如下输出。是否有任何选项xargs
可以指定一次显示整个实例的输出?
Executing in host1:
Output of: cmd1; cmd2;
Executing in host2:
Output of: cmd1; cmd2;
Executing in host3:
Output of: cmd1; cmd2;
Executing in host4:
Output of: cmd1; cmd2;
答案1
见面GNU 并行(sudo apt install parallel
):
GNU parallel 确保命令的输出与您按顺序运行命令时的输出相同。
如果您现在使用 xargs 和 tee,您会发现 GNU parallel 非常易于使用,因为 GNU parallel 被编写为具有与 xargs 相同的选项。
我无法测试它,但在你的情况下,命令应该简单是:
parallel -n 2 -P $MaxInstance $(command -v bash) -c 'echo_var "$1"' _ {}
请注意,该moreutils
软件包提供了parallel
与 GNU parallel 不同的命令。
示例运行
此示例echo {} start; sleep 1; echo {} ready
针对参数1
、2
和运行3
,首先使用xargs
,然后使用parallel
:
$ echo -e '1\n2\n3' | xargs -n1 -P3 -I{} bash -c 'echo {} start; sleep 1; echo {} ready'
2 start
1 start
3 start
2 ready
1 ready
3 ready
$ parallel 'echo {} start; sleep 1; echo {} ready' ::: 1 2 3
1 start
1 ready
2 start
2 ready
3 start
3 ready
当然,该echo |
方法同样有效parallel
,我只是喜欢上面显示的参数列表功能——它的作用完全相同。
parallel
如果你因为没有预装、难以安装/更新或类似原因而犹豫不决,我强烈推荐该程序作者的博客文章不安装 GNU Parallel 的借口。