在Bash脚本中传递参数给Ansible Playbook失败,报错求助
解决Ansible传递参数时的Playbook找不到问题
问题根源
你的脚本错误地将Ansible参数拼接成带引号的字符串,导致Bash执行ansible-playbook时,把整个参数字符串当作单个参数解析。这会让Ansible误以为" -e \"POSTGRES_cluster_name=ansiblecluster\""是第二个Playbook的路径,因此抛出"找不到Playbook"的错误。
修复方案
1. 用数组存储参数
将参数定义改为Bash数组,保留每个参数的独立性:
# 替换原来的参数定义 ANSIBLE_POSTGRES_PLAYBOOK_PARAMETER=(-e "POSTGRES_cluster_name=ansiblecluster")
2. 修改run_playbook函数的执行逻辑
在执行ansible-playbook时,正确展开后续参数,而非传递单个字符串:
run_playbook() { LOG_MSG="Running playbook ${1}" if [ "${#@}" -gt 1 ]; then LOG_MSG="${LOG_MSG} with additional parameters: ${*:2}" fi ANSIBLE_CONFIG_FILE="${INSTALL_ANSIBLE_TARGET_PATH}/${ANSIBLE_CONFIG_DIR}/${ANSIBLE_CONFIG_FILENAME}" log_i "${LOG_MSG} using main config ${ANSIBLE_CONFIG_FILE} file." # 正确展开所有后续参数 sudo ansible-playbook -i "${ANSIBLE_CONFIG_FILE}" -l "${LINUX_HOST}" "${1}" "${@:2}" log_i "Ansible playbook ${1} execution was finished." }
3. 调整函数调用
调用run_playbook时直接传递数组:
run_playbook "${PLAYBOOKS_DIRECTORY}/${ANSIBLE_POSTGRES_PLAYBOOK_FILENAME}" "${ANSIBLE_POSTGRES_PLAYBOOK_PARAMETER[@]}"
修改后的完整脚本
#!/usr/bin/env bash set -e +x # Variables LINUX_HOST="ubuntu" INSTALL_ANSIBLE_TARGET_PATH="/tmp/ansible-inst" ANSIBLE_CONFIG_DIR="inventory" ANSIBLE_CONFIG_FILENAME="hosts.yml" ANSIBLE_PLAYBOOKS_DIR="playbooks" ANSIBLE_PREPARE_PLAYBOOK_FILENAME="linux-prepare-deploy.yml" ANSIBLE_POSTGRES_PLAYBOOK_FILENAME="postgresql-server-install.yml" # 改用数组存储参数 ANSIBLE_POSTGRES_PLAYBOOK_PARAMETER=(-e "POSTGRES_cluster_name=ansiblecluster") # Utils run_playbook() { LOG_MSG="Running playbook ${1}" if [ "${#@}" -gt 1 ]; then LOG_MSG="${LOG_MSG} with additional parameters: ${*:2}" fi ANSIBLE_CONFIG_FILE="${INSTALL_ANSIBLE_TARGET_PATH}/${ANSIBLE_CONFIG_DIR}/${ANSIBLE_CONFIG_FILENAME}" log_i "${LOG_MSG} using main config ${ANSIBLE_CONFIG_FILE} file." # 正确展开参数 sudo ansible-playbook -i "${ANSIBLE_CONFIG_FILE}" -l "${LINUX_HOST}" "${1}" "${@:2}" log_i "Ansible playbook ${1} execution was finished." } # Main functions _ansible_run() { cd "${INSTALL_ANSIBLE_TARGET_PATH}" PLAYBOOKS_DIRECTORY="${INSTALL_ANSIBLE_TARGET_PATH}/${ANSIBLE_PLAYBOOKS_DIR}" run_playbook "${PLAYBOOKS_DIRECTORY}/${ANSIBLE_PREPARE_PLAYBOOK_FILENAME}" # 传递数组参数 run_playbook "${PLAYBOOKS_DIRECTORY}/${ANSIBLE_POSTGRES_PLAYBOOK_FILENAME}" "${ANSIBLE_POSTGRES_PLAYBOOK_PARAMETER[@]}" }
原理说明
Bash中,字符串拼接的带引号参数会被当作单个整体传递给命令,而数组能让每个参数(比如-e和POSTGRES_cluster_name=ansiblecluster)保持独立身份,被ansible-playbook正确解析为选项和对应的值,而非误判为Playbook路径。
内容的提问来源于stack exchange,提问作者Michael Linker
相关产品推荐
相关产品推荐

