出于安全原因,我编写了一个简短的bash脚本来包装ansible playbook命令。它并不复杂,大多数脚本在这里都无关紧要。最后,我将来自脚本参数生成的变量的ansible命令放在一起,如下所示:
ansible-playbook -k $user -i hosts-staging $limit $tags $additionalargs site.yml
生成的命令大部分都有效,除了$ additionalargs似乎没有任何效果。所以我做了一个回声,看看脚本实际生成了什么:
echo ansible-playbook -k $user -i hosts-staging $limit $tags $additionalargs site.yml
output: ansible-playbook -k -u pi -i hosts-staging -l tcameras --tags fulllaunch --extra-vars "agraphite_force_restart=true" site.yml
这看起来完全符合预期,但似乎没有传递--extra-vars参数。 所以我复制了echo产生的行,将它粘贴在控制台中并点击回车,这完全有效,包括--extra-vars参数。
因此脚本会生成我想要的内容,如果我手动提供脚本生成的命令,它可以工作......但是当脚本本身执行命令时,它不起作用,或者至少不完全。
有人能给我一些关于可能出错的提示吗?下面是完整的脚本供参考,虽然由于输出是预期的,我不认为问题在这里,而是有一些我不知道的bash pecularity。
#!/bin/bash
# brief Makes graphite deployment via Ansible saver by wrapping it into a script that only needs the most common variables, does not apply to the whole inventory by default, and uses the current staging inventory.
# args (3) Expects 3 arguments: what to do, who to do it with, and if it should do it with all of them or just with one individual instance
# arg $1 What to do. Valid values are "deploy", "launch" or "restart".
# arg $2 Who to do it with. Valid values are "cameras", "servers" or "all".
# arg $3 Optional: Pass an IP from the inventory to apply the action to.
# error codes:
# 1: Unexpected number of arguments
# 2: Invalid first argument
# 3: Invalid second argument
# 4: Invalid third argument (optional)
# 5: Optional third argument not compatible with second argument
additionalargs=""
if [ $# -lt 2 ]; then
echo "Unexpected number of arguments (2 expected). Please pass what (\"deploy\", \"launch\" or \"restart\") and who (\"cameras\", \"servers\" or \"all\")"
exit 1
fi
if [ $1 == "launch" ]; then
tags="--tags fulllaunch"
elif [ $1 == "restart" ]; then
tags="--tags fulllaunch"
additionalargs='--extra-vars "agraphite_force_restart=true"'
elif [ $1 != "deploy" ]; then
echo "Invalid argument: "$1"! Must be either \"launch\", \"deploy\" or \"restart\"!"
exit 2
else
tags=""
fi
if [ $2 == "cameras" ]; then
limit="-l tcameras"
user="-u pi"
elif [ $2 == "servers" ]; then
limit="-l tservers"
user="-u ubuntu"
elif [ $2 == "all" ]; then
limit=""
user="both"
else
echo "Invalid argument: "$2"! Must be either \"cameras\", \"servers\", <ip> or \"all\"!"
exit 3
fi
if [ $# -eq 3 ]; then
if [[ $3 == *.*.*.* ]]; then #quite a superficial check for the validity of an ip address, but it serves to prevent dangerous input
limit="-l "$3
else
echo "Error: optional third parameter must be a valid ip-address!"
exit 4
fi
if [ $user == "both" ]; then
echo "Error: specific ip cannot be used with parameter \"all\"."
exit 5
fi
fi
if [[ $user == "both" ]]; then
#do actions for both cameras and servers
ansible-playbook -k -u ubuntu -i hosts-staging -l tcameras $tags $additionalargs site.yml
ansible-playbook -k -u pi -i hosts-staging -l tservers $tags $additionalargs site.yml
else
echo ansible-playbook -k $user -i hosts-staging $limit $tags $additionalargs site.yml
ansible-playbook -k $user -i hosts-staging $limit $tags $additionalargs site.yml
fi
答案 0 :(得分:0)
我在编写另一个涉及相当复杂的curl命令的脚本时找到了这个解决方案。 首先我发现你可以使用
set -x
在脚本中让它显示扩展的命令,而我对报价扩展产生的混乱感到非常恐惧。它在回声中很好地扩展,但是通过整个事物作为参数构建了一个神秘的引号迷宫。我也试过引用变量,但Ansible不太喜欢这个。
我发现对于带有许多参数的长命令本身可能包含引号,最好将整个命令写入双引号内的字符串中并转义参数中的任何引号,然后将整个事物传递给eval。 / p>
在这种特殊情况下,实际工作的命令如下所示:
eval "ansible-playbook -k $user -i hosts-staging $limit $tags $additionalargs site.yml"