如何正确处理Bash环境变量中Java系统属性的引号异常问题
问题原因
这是Bash的单词拆分机制导致的:普通字符串变量存储的引号不会被Bash识别为参数边界,你之前的两种错误写法问题分别是:
- 直接执行
java $OPTS Main时,Bash会按空格拆分变量内容,把-Dbazinga="foo、bar"拆成两个独立参数,Java会把bar"识别为主类名,自然找不到类 - 加引号执行
java "$OPTS" Main时,整个变量内容会被当成单个参数传给Java,参数里的引号也会被原样传入,所以最终读出的属性值自带多余引号
解决方案
方案1:使用Bash数组(最推荐)
数组原生支持保存带空格的参数,不会出现拆分异常,操作方式如下:
# 定义数组存储参数 OPTS=(-Dbazinga="foo bar") # 执行时展开数组,每个元素会作为独立参数传入 java "${OPTS[@]}" Main
这种方式没有安全风险,Bash 3.0及以上版本都支持,是处理多参数的首选方案。如果需要给多个命令传参,直接复用数组即可。
方案2:用xargs解析参数(适配需要导出环境变量的场景)
如果你需要把参数导出为环境变量给子进程使用(数组默认不会被子进程继承),可以用xargs自动解析引号里的空格:
# 导出环境变量的方式不变 export OPTS="-Dbazinga=\"foo bar\"" # 用xargs解析参数后执行 echo "$OPTS" | xargs java Main
方案3:使用eval(不推荐,仅作兼容说明)
如果必须兼容极老的Bash版本,可以用eval强制让Bash解析变量里的引号,但是注意仅在你完全控制OPTS内容的场景下使用,如果OPTS包含不可信内容会有命令注入风险:
eval "java $OPTS Main"
内容的提问来源于stack exchange,提问作者jan.n.nowak
相关产品推荐
相关产品推荐

