运行 一个 bash for 并行循环
run a bash for loop in parallel
我有这个脚本,它在本地保管库系统中为每个主机执行凭据查找,然后为其运行一个 ansible-playbook。
#!/bin/bash
for host in `cat ~/.ansible/hosts`
do
SECRET=`/opt/vault/bin/get-admin-credential --tag=$host`
HOST=`echo $SECRET | cut -d ';' -f1`
LOGIN=`echo $SECRET | cut -d ';' -f2`
DOMAIN=`echo $SECRET | cut -d ';' -f3`
PWD=`echo $SECRET | cut -d ';' -f4`
if [ -z "$DOMAIN" ]; then
ansible-playbook -i ~/.ansible/hosts ~/.ansible/windows.yml -e "ansible_host=$HOST ansible_user=$LOGIN ansible_password=$PWD" --limit $host
else
ansible-playbook -i ~/.ansible/hosts ~/.ansible/windows.yml -e "ansible_host=$HOST ansible_user=$LOGIN@$DOMAIN ansible_password=$PWD" --limit $host
fi
done
这会按顺序循环遍历每个主机,我已经尝试过使用 GNU parallel
但无法执行我想要的操作,运行 for 循环与 5 并行。
有人给我指点正确的方向吗?
我没有任何 "ansibles" 或 "vaults",所以这完全未经测试,但可能让你靠近:
doit(){
host=""
SECRET=$(/opt/vault/bin/get-admin-credential --tag=$host)
HOST=$(echo $SECRET | cut -d ';' -f1)
LOGIN=$(echo $SECRET | cut -d ';' -f2)
DOMAIN=$(echo $SECRET | cut -d ';' -f3)
PWD=$(echo $SECRET | cut -d ';' -f4)
if [ -z "$DOMAIN" ]; then
ansible-playbook -i ~/.ansible/hosts ~/.ansible/windows.yml -e "ansible_host=$HOST ansible_user=$LOGIN ansible_password=$PWD" --limit $host
else
ansible-playbook -i ~/.ansible/hosts ~/.ansible/windows.yml -e "ansible_host=$HOST ansible_user=$LOGIN@$DOMAIN ansible_password=$PWD" --limit $host
fi
}
# Export doit function to subshells created by GNU Parallel
export -f doit
parallel -a ~/.ansible/hosts doit
在文体上,可能有一些改进。首先,由大写字母组成的shell变量是保留的,所以你不应该使用HOST
、DOMAIN
等。另外,你可以简化所有难看的切割和回显来提取通过使用 IFS=';'
和 read
来自 SECRET 的变量,如下所示:
SECRET=$(/opt/vault/bin/get-admin-credential --tag=$host)
IFS=';' read host login domain pwd <<< "$SECRET"
所以,我最好也是最后的答案是:
doit(){
host=""
secret=$(/opt/vault/bin/get-admin-credential --tag=$host)
IFS=';' read host login domain pwd <<< "$secret"
if [ -z "$domain" ]; then
ansible-playbook -i ~/.ansible/hosts ~/.ansible/windows.yml -e "ansible_host=$host ansible_user=$login ansible_password=$pwd" --limit $host
else
ansible-playbook -i ~/.ansible/hosts ~/.ansible/windows.yml -e "ansible_host=$host ansible_user=$login@$domain ansible_password=$pwd" --limit $host
fi
}
# Export doit function to subshells created by GNU Parallel
export -f doit
parallel -a ~/.ansible/hosts doit
您只需要 运行 ansible-playbook
在后台使用 &
命令终止符。不过请注意,整个循环可以得到简化和改进。
run_playbook () {
ansible-playbook -i ~/.ansible/hosts \
-e "ansible_host= ansible_login= ansible_password=" \
~/.ansible/windows.yml --limit ""
}
while IFS= read -r host; do
secret=$(/opt/vault/bin/get-admin-credential --tag="$host")
IFS=";" read -r shost slogin sdomain spasswd _ <<< "$secret"
if [[ -n $sdomain ]]; then
login="$slogin@$sdomain"
fi
run_playbook "$host" "$shost" "$login" "$password" &
done < ~/.ansible/hosts
我有这个脚本,它在本地保管库系统中为每个主机执行凭据查找,然后为其运行一个 ansible-playbook。
#!/bin/bash
for host in `cat ~/.ansible/hosts`
do
SECRET=`/opt/vault/bin/get-admin-credential --tag=$host`
HOST=`echo $SECRET | cut -d ';' -f1`
LOGIN=`echo $SECRET | cut -d ';' -f2`
DOMAIN=`echo $SECRET | cut -d ';' -f3`
PWD=`echo $SECRET | cut -d ';' -f4`
if [ -z "$DOMAIN" ]; then
ansible-playbook -i ~/.ansible/hosts ~/.ansible/windows.yml -e "ansible_host=$HOST ansible_user=$LOGIN ansible_password=$PWD" --limit $host
else
ansible-playbook -i ~/.ansible/hosts ~/.ansible/windows.yml -e "ansible_host=$HOST ansible_user=$LOGIN@$DOMAIN ansible_password=$PWD" --limit $host
fi
done
这会按顺序循环遍历每个主机,我已经尝试过使用 GNU parallel
但无法执行我想要的操作,运行 for 循环与 5 并行。
有人给我指点正确的方向吗?
我没有任何 "ansibles" 或 "vaults",所以这完全未经测试,但可能让你靠近:
doit(){
host=""
SECRET=$(/opt/vault/bin/get-admin-credential --tag=$host)
HOST=$(echo $SECRET | cut -d ';' -f1)
LOGIN=$(echo $SECRET | cut -d ';' -f2)
DOMAIN=$(echo $SECRET | cut -d ';' -f3)
PWD=$(echo $SECRET | cut -d ';' -f4)
if [ -z "$DOMAIN" ]; then
ansible-playbook -i ~/.ansible/hosts ~/.ansible/windows.yml -e "ansible_host=$HOST ansible_user=$LOGIN ansible_password=$PWD" --limit $host
else
ansible-playbook -i ~/.ansible/hosts ~/.ansible/windows.yml -e "ansible_host=$HOST ansible_user=$LOGIN@$DOMAIN ansible_password=$PWD" --limit $host
fi
}
# Export doit function to subshells created by GNU Parallel
export -f doit
parallel -a ~/.ansible/hosts doit
在文体上,可能有一些改进。首先,由大写字母组成的shell变量是保留的,所以你不应该使用HOST
、DOMAIN
等。另外,你可以简化所有难看的切割和回显来提取通过使用 IFS=';'
和 read
来自 SECRET 的变量,如下所示:
SECRET=$(/opt/vault/bin/get-admin-credential --tag=$host)
IFS=';' read host login domain pwd <<< "$SECRET"
所以,我最好也是最后的答案是:
doit(){
host=""
secret=$(/opt/vault/bin/get-admin-credential --tag=$host)
IFS=';' read host login domain pwd <<< "$secret"
if [ -z "$domain" ]; then
ansible-playbook -i ~/.ansible/hosts ~/.ansible/windows.yml -e "ansible_host=$host ansible_user=$login ansible_password=$pwd" --limit $host
else
ansible-playbook -i ~/.ansible/hosts ~/.ansible/windows.yml -e "ansible_host=$host ansible_user=$login@$domain ansible_password=$pwd" --limit $host
fi
}
# Export doit function to subshells created by GNU Parallel
export -f doit
parallel -a ~/.ansible/hosts doit
您只需要 运行 ansible-playbook
在后台使用 &
命令终止符。不过请注意,整个循环可以得到简化和改进。
run_playbook () {
ansible-playbook -i ~/.ansible/hosts \
-e "ansible_host= ansible_login= ansible_password=" \
~/.ansible/windows.yml --limit ""
}
while IFS= read -r host; do
secret=$(/opt/vault/bin/get-admin-credential --tag="$host")
IFS=";" read -r shost slogin sdomain spasswd _ <<< "$secret"
if [[ -n $sdomain ]]; then
login="$slogin@$sdomain"
fi
run_playbook "$host" "$shost" "$login" "$password" &
done < ~/.ansible/hosts