如何避免Bash命令行参数展开?Payara asadmin报错求助
问题根源拆解
你遇到的bash: -Dlogback.configurationFile=${com.sun.aas.instanceRoot}/lib/classes/logback.xml: bad substitution错误,其实是Bash的参数展开机制在搞鬼,具体有两个核心原因:
- Bash不接受带点的变量名:Bash里的变量名只能由字母、数字和下划线组成,
.是不允许出现在变量名里的。你命令里的${com.sun.aas.instanceRoot}包含多个点,Bash直接判定这是无效的变量语法,所以抛出了"bad substitution"错误。 - 你不需要Bash解析这个表达式:就算变量名合法,Bash也会自动把
${xxx}替换成当前环境中该变量的值,但你的需求是让这个表达式原封不动传给Payara的asadmin命令,用来在domain.xml里生成对应的配置项,所以必须阻止Bash的自动展开行为。
搞定它:阻止Bash参数展开的几种方式
要让${com.sun.aas.instanceRoot}完完整整被asadmin接收,你可以用下面几种方法:
方法1:用单引号把整个JVM选项包起来(最推荐)
单引号在Bash里是「完全屏蔽魔法」的存在——任何特殊字符在单引号里都会变成普通字符,不会被Bash解析。直接把你的JVM选项用单引号裹住:
./asadmin create-jvm-options '-Dlogback.configurationFile=${com.sun.aas.instanceRoot}/lib/classes/logback.xml'
这样Bash会把单引号里的内容原封不动当作一个参数传给asadmin,完全不会碰${...}那部分。
方法2:给美元符号加反斜杠转义
如果你不想用单引号,可以给$前面加个\,告诉Bash:「这只是个普通的美元符号,别瞎解析」:
./asadmin create-jvm-options -Dlogback.configurationFile=\${com.sun.aas.instanceRoot}/lib/classes/logback.xml
\$会让Bash把美元符号当作普通字符处理,自然就不会尝试展开后面的变量了。
方法3:双引号?别用在这儿!
虽然双引号也能阻止部分展开,但Bash在双引号里还是会尝试解析合法的变量名。你的变量名带点,就算用双引号包起来,Bash还是会报错bad substitution,所以这个方法对你的场景不适用。如果变量名是合法的(比如把点换成下划线),双引号可能有用,但这里咱们直接用前两种方法更稳妥。
验证结果
执行上面的正确命令后,你去查看domain.xml,就能看到你期望的条目了:
<jvm-options>-Dlogback.configurationFile=${com.sun.aas.instanceRoot}/lib/classes/logback.xml</jvm-options>
内容的提问来源于stack exchange,提问作者David Laci
相关产品推荐
相关产品推荐

