我有一个小脚本,我将在每个openstack的租户中获取并在python的帮助下获取一些输出。报告生成花了太长时间,我被建议使用xargs
。我之前的代码如下所示。
#!/bin/bash
cd /scripts/cloud01/floating_list
rm -rf ./reports/openstack_reports/
mkdir -p ./reports/openstack_reports/
source ../creds/base
for tenant in A B C D E F G H I J K L M N O P Q R S T
do
source ../creds/$tenant
python ../tools/openstack_resource_list.py > ./reports/openstack_reports/$tenant.html
done
lftp -f ./lftp_script
现在我将xargs放在脚本中,脚本看起来像这样。
#!/bin/bash
cd /scripts/cloud01/floating_list
rm -rf ./reports/openstack_reports/
mkdir -p ./reports/openstack_reports/
source ../creds/base
# Need xargs idea below
cat tenants_list.txt | xargs -P 8 -I '{}' # something that takes the tenant name and source
TENANT_NAME={}
python ../tools/openstack_resource_list.py > ./reports/openstack_reports/$tenant.html
lftp -f ./lftp_script
在这个脚本中我应该如何实现source ../creds/$tenant
?因为在处理每个租户时,它也需要来源,我不知道如何将xargs包含在并行执行中。
xargs
无法轻松运行shell函数......但它可以运行shell。
# If the tenant names are this simple, don't put them in a file
printf '%s\n' {A..T} |
xargs -P 8 -I {} bash -c 'source ../creds/"$0"
python ../tools/openstack_resource_list.py > ./reports/openstack_reports/"$0".html' {}
有些晦涩难懂,bash -c '...'
之后的论点在剧本中被曝光为$0
。
如果你想把租户留在一个文件中,xargs -a filename
是一个避免useless use of cat
的好方法,虽然它不能移植到所有xargs
实现。 (用xargs ... <filename
重定向显然是完全可移植的。)
为了提高效率,您可以重构脚本以循环尽可能多的参数:
printf '%s\n' {A..T} |
xargs -n 3 -P 8 bash -c 'for tenant; do
source ../creds/"$tenant"
python ../tools/openstack_resource_list.py > ./reports/openstack_reports/"$tenant".html
done' _
这将最多运行8个并行shell实例,每个实例最多分配3个租户(实际上实际上只有7个实例),尽管有少量参数,性能差异可能微不足道。
因为我们现在实际上正在接收一个参数列表,所以我们将_
作为填充$0
的值传递(因为它需要被设置为某个东西,以便正确地获得真正的参数)。
如果source
可能会进行修改,而这些修改并不总是保证在下一次迭代中被source
覆盖(比如说,有些租户的变量需要为其他一些租户设置?)会使事情变得复杂,但如果qaxswpoi可能会发布一个单独的问题,如果你真的需要帮助来解决这个问题;或者只是回到第一个变量,其中每个租户都在一个单独的shell实例中运行。
使用GNU Parallel,它看起来像这样:
#!/bin/bash
cd /scripts/cloud01/floating_list
rm -rf ./reports/openstack_reports/
mkdir -p ./reports/openstack_reports/
source ../creds/base
doit() {
source ../creds/"$1"
python ../tools/openstack_resource_list.py > ./reports/openstack_reports/"$1".html
}
env_parallel doit ::: {A..T}
lftp -f ./lftp_script
env_parallel
将环境复制到每个命令中 - 包括函数。然后运行parallel
,并行运行每个核心一个作业。
根据任务的不同,并行运行更多或更少可能更快或更慢。使用-j8
并行调整8个作业或-j200%
调整每个核心2个作业。