出于安全原因,我编写了一个简短的 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 生成的行,将其粘贴到控制台中并按 Enter 键,这完全有效,包括 --extra-vars 参数。
因此,脚本生成了我想要的内容,如果我手动提供脚本生成的命令,它就可以工作......但是当脚本本身执行命令时,它就不起作用,或者至少不完全。
有人可以给我一个提示,告诉我可能会出什么问题吗?下面是供参考的完整脚本,尽管由于输出符合预期,我不希望问题出现在此处,而是有一些我不知道的 bash 特殊性。
#!/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