Maven构建中Bash变量$VAR与${VAR}写法差异原因排查
This difference has nothing to do with Bash itself—it's entirely about how Maven's resource filtering mechanism processes your script file during the build phase. Here's a breakdown of what's happening:
1. Maven's Default Resource Filtering Behavior
Maven uses the maven-resources-plugin to handle resource files (like your Bash startup script) during builds. By default, this plugin looks for placeholder variables in the format ${variableName}. When it finds these, it replaces them with matching values from three sources:
- Maven properties defined in your
pom.xml - System properties available at build time
- Environment variables present when the build runs
On the other hand, the syntax $VAR isn't recognized as a Maven placeholder by default. Maven treats this as plain text and leaves it untouched in the final built script.
2. Applying This to Your Scenario
Let's tie this directly to your observations:
When using
$JAVA_OPTSin the script:
Maven doesn't interpret$JAVA_OPTSas a placeholder, so it stays exactly as written in the finished script. When you run the script later, Bash takes over and replaces$JAVA_OPTSwith the environment variable's value at runtime (which you noted is-mx4096M).When using
${JAVA_OPTS}in the script:
Maven immediately recognizes${JAVA_OPTS}as a placeholder during the build. It pulls theJAVA_OPTSenvironment variable value that existed at build time (in your case,-Xmx3072m -XX:MaxPermSize=1024m -Djava.net.preferIPv4Stack=true) and replaces the placeholder with this value directly in the script. By the time you run the script, there's no variable left to expand—Maven already did the work.
3. Why Bash Execution Output Is the Same
You mentioned both scripts produce identical output when run in Bash. That's likely because, in your test environment, the JAVA_OPTS environment variable at runtime matches the value that was present during the build for the ${JAVA_OPTS} case. If you were to change the runtime JAVA_OPTS value, the $JAVA_OPTS script would reflect the new value, while the ${JAVA_OPTS} script would still use the fixed build-time value.
4. How to Control This Behavior
If you want to prevent Maven from replacing ${VAR} placeholders in your Bash scripts, you have a few straightforward options:
- Disable resource filtering specifically for the script file in your
pom.xmlconfiguration formaven-resources-plugin. - Escape the curly braces in the script using
\${VAR}—Maven will treat this as plain text and leave it as${VAR}for Bash to process later. - Configure the plugin to use a different placeholder delimiter (though this is less common for Bash scripts).
内容的提问来源于stack exchange,提问作者Zeinab Abbasimazar

