如何在Bash脚本传递JSON参数时保留双引号?
解决Bash传递JSON参数时双引号丢失的问题
在执行Java Maven应用的run.sh脚本中,传递dynamicOptionsJson这个JSON字符串参数时,应用收到的JSON丢失了双引号,变成{bigqueryTable: table, dummyOption: hehexd},尝试了.env中的两种定义方式均无效,以下是可行的解决方法:
原文件内容
run.sh
#!/bin/bash source ./.env mvn clean compile exec:java -P dataflow-runner -Dexec.args=" --project=${project} \ --runner=DataflowRunner \ --region=${region} \ --gcpTempLocation=${gcpTempLocation} \ --tempLocation=${tempLocation} \ --serviceAccount=${serviceAccount} \ --dynamicOptionsJson=\"${dynamicOptionsJson}\" \ "
.env
project=project-name region=the-region serviceAccount=an-account gcpTempLocation=gs://cloud_storage_bucket/temp tempLocation=gs://cloud_storage_bucket/temp dynamicOptionsJson='{"bigqueryTable": "table", "dummyOption": "hehexd"}' #dynamicOptionsJson="{\\"bigqueryTable\\": \\"table\\", \\"dummyOption\\": \\"hehexd\\"}"
问题根源
Bash的引号解析规则会导致嵌套的引号被意外剥离,尤其是在-Dexec.args="..."这种外层双引号包裹的结构中,变量展开时内部的引号会被Bash处理,最终传递给应用的参数丢失了双引号。
解决方法
方法1:使用Bash数组构建参数(推荐)
用数组管理每个参数,能避免引号解析混乱,确保每个参数(包括JSON字符串)被完整传递:
修改run.sh:
#!/bin/bash source ./.env # 用数组定义所有参数,每个元素独立处理引号 args=( --project="${project}" --runner=DataflowRunner --region="${region}" --gcpTempLocation="${gcpTempLocation}" --tempLocation="${tempLocation}" --serviceAccount="${serviceAccount}" --dynamicOptionsJson="${dynamicOptionsJson}" ) # 将数组参数传递给Maven exec插件 mvn clean compile exec:java -P dataflow-runner -Dexec.args="${args[*]}"
方法2:修正.env定义并简化run.sh参数写法
- 修正.env中的
dynamicOptionsJson定义,用单引号包裹完整JSON,内部双引号直接使用(单引号内的内容会被Bash原样保留):
dynamicOptionsJson='{"bigqueryTable": "table", "dummyOption": "hehexd"}'
- 修改run.sh中
--dynamicOptionsJson的参数行,直接用双引号包裹变量,无需额外转义:
#!/bin/bash source ./.env mvn clean compile exec:java -P dataflow-runner -Dexec.args=" --project=${project} \ --runner=DataflowRunner \ --region=${region} \ --gcpTempLocation=${gcpTempLocation} \ --tempLocation=${tempLocation} \ --serviceAccount=${serviceAccount} \ --dynamicOptionsJson="${dynamicOptionsJson}" \ "
验证方法
可以在run.sh中添加一行echo "${args[*]}"(数组方法)或者echo "--dynamicOptionsJson=${dynamicOptionsJson}",执行脚本后查看输出,确认JSON字符串的双引号是否被正确保留。
内容的提问来源于stack exchange,提问作者david7596
相关产品推荐
相关产品推荐

