修复Bash语法错误,解决Jenkins+Azure CLI自动化VM启停作业问题
问题排查与修复方案
错误根源
你的脚本出现syntax error near unexpected token 'fi'主要有两个核心原因:
- 语法边界错误:
vm_ids=''语句后没有换行或分号分隔,直接紧跟if语句,导致Shell无法正确识别命令的结束位置; - 解释器兼容性问题:Jenkins默认可能用
sh执行脚本,但你使用了Bash特有的[[ ]]条件判断语法,sh并不支持这个写法。
另外你的代码片段里az vm show命令不完整,我也一起帮你补全并优化了逻辑。
修复后的完整脚本
#!/bin/bash # 指定用Bash解释器执行,避免sh兼容性问题 # 先列出带目标标签的所有资源(可选,用于日志验证) az resource list --tag Restart=${TAG_RESTART} --query "[].{Name:name,RG:resourceGroup}" -o table # 初始化VM ID数组 vm_ids=() # 根据OPTION参数执行对应操作 if [[ "${OPTION}" == 'start' ]]; then # 获取所有带标签的虚拟机ID vm_ids=($(az resource list --tag Restart=${TAG_RESTART} --query "[?type=='Microsoft.Compute/virtualMachines'].id" -o tsv)) # 循环启动每个VM for i in "${vm_ids[@]}" do echo "Starting VM: $i" az vm start --ids "$i" # 显示VM启动后的状态 az vm show -d --ids "$i" --query "{Name:name, PowerState:powerState}" -o table done elif [[ "${OPTION}" == 'stop' ]]; then # 获取所有带标签的虚拟机ID vm_ids=($(az resource list --tag Restart=${TAG_RESTART} --query "[?type=='Microsoft.Compute/virtualMachines'].id" -o tsv)) # 循环停止每个VM for i in "${vm_ids[@]}" do echo "Stopping VM: $i" az vm stop --ids "$i" # 显示VM停止后的状态 az vm show -d --ids "$i" --query "{Name:name, PowerState:powerState}" -o table done else echo "Error: Invalid OPTION value. Must be 'start' or 'stop'" exit 1 fi
关键细节说明
- 指定Bash解释器:开头的
#!/bin/bash必须添加,确保Jenkins用Bash执行脚本,兼容[[ ]]和数组操作; - 变量引号包裹:所有变量引用(比如
"$i")都用双引号包裹,避免VM名称含特殊字符时出现解析错误; - 数组优化:把
vm_ids初始化为空数组,更符合Bash的语法规范,确保每个VM ID作为独立元素被处理; - 错误处理:增加了
else分支捕获无效参数,避免脚本静默失败,方便在Jenkins控制台快速定位问题; - 日志增强:添加
echo和状态查询命令,让你能直观看到每个VM的执行结果。
Jenkins配置注意事项
- 确保Jenkins节点已安装Azure CLI,并且通过服务主体认证(
az login --service-principal)完成Azure账号授权,避免手动登录的会话过期问题; - 作业参数配置:
- 添加字符串参数
OPTION,默认值设为start,描述里明确标注可选值为start/stop; - 添加字符串参数
TAG_RESTART,用于指定目标VM的标签值;
- 添加字符串参数
- 构建步骤选择「Execute shell」,将修复后的脚本直接粘贴进去即可。
内容的提问来源于stack exchange,提问作者bonafide
相关产品推荐
相关产品推荐

