Rake任务更新OpsWorks栈CustomJson时$字符丢失问题求助
问题原因及解决方法
原因分析
$字符丢失的核心原因是Shell对双引号内的变量展开行为:
- 你最后一条命令里的
"会被Shell解析成双引号,导致--custom-json的参数值被双引号包裹 - 当
updated_json中包含$开头的内容(比如Git哈希里的$、CustomJson中的变量占位符),Shell会把它当作环境变量尝试解析;如果找不到对应环境变量,就会将其替换为空字符串,最终导致$字符丢失
解决方法
方法1:用Ruby的Shellwords.escape转义参数
通过Shell转义处理updated_json,让Shell把整个JSON字符串当作单一参数,不解析其中的特殊字符:
require 'shellwords' # 替换原最后一行命令 escaped_json = Shellwords.escape(updated_json) `aws opsworks \ --region us-east-1 \ update-stack \ --stack-id #{stack_id} \ --custom-json #{escaped_json}`
方法2:改用AWS Ruby SDK直接调用(推荐)
彻底绕过Shell命令的转义问题,直接用AWS SDK操作OpsWorks,这是最可靠的实现方式:
先确保Gemfile中添加aws-sdk-opsworks,然后修改任务代码:
require 'aws-sdk-opsworks' desc "update revision in custom json of stack" task :update_stack_revision, [:revision, :stack_id] do |t, arg| revision = arg[:revision] stack_id = arg[:stack_id] opsworks = Aws::OpsWorks::Client.new(region: 'us-east-1') # 获取栈配置 stack_response = opsworks.describe_stacks(stack_ids: [stack_id]) raw_custom_json = stack_response.stacks[0].custom_json # 解析并更新版本号 parsed_custom_json = JSON.parse(raw_custom_json) parsed_custom_json["git"]["revision"] = revision updated_json = JSON.generate(parsed_custom_json) # 更新栈属性 opsworks.update_stack( stack_id: stack_id, custom_json: updated_json ) end
方法3:调整Shell命令的引号用法
用单引号包裹参数,因为Shell在单引号内不会解析$变量:
# 替换原最后一行命令,直接用单引号包裹JSON `aws opsworks \ --region us-east-1 \ update-stack \ --stack-id #{stack_id} \ --custom-json '#{updated_json}'`
注意:如果updated_json本身包含单引号,这种方式会出错,通用性不如前两种方法。
内容的提问来源于stack exchange,提问作者zetain
相关产品推荐
相关产品推荐

