
Picocli 本身不会忽略美元符号,问题根源在于 Shell 对 $ 的变量展开行为;解决方案是使用单引号包裹参数或对 $ 进行转义,确保字符串原样传递给 Java 应用。
picocli 本身不会忽略美元符号,问题根源在于 shell 对 `$` 的变量展开行为;解决方案是使用单引号包裹参数或对 `$` 进行转义,确保字符串原样传递给 java 应用。
在基于 Unix/Linux/macOS 的 Shell(如 bash、zsh)中,$ 符号具有特殊含义——它用于引用环境变量或执行命令替换(例如 $PATH 或 $((2+3)))。当你运行如下命令:
java -jar encryption.jar passwd-enc -password "test23$34" -key /user/local/key.txt
Shell 会在将参数传递给 Java 之前,尝试解析 "test23$34":由于 $34 不是一个合法的变量名(变量名不能以数字开头),某些 Shell 可能静默忽略 $34,导致实际传入的是 "test234";更典型的情况是,若存在名为 34 的变量(如 34=xxx),则会被展开为对应值。
✅ 正确做法是阻止 Shell 解析 $,有两种推荐方式:
-
使用单引号包裹整个密码(推荐):
单引号内的所有字符均被视为字面量,包括 $、\、* 等:java -jar encryption.jar passwd-enc -password 'test23$34' -key /user/local/key.txt
-
在双引号内对 $ 进行转义:
使用反斜杠 \ 转义 $,保留双引号的其他特性(如支持换行符等):java -jar encryption.jar passwd-enc -password "test23\$34" -key /user/local/key.txt
⚠️ 注意事项:
- Windows CMD/PowerShell 行为不同:CMD 中 $ 无特殊含义,无需转义;PowerShell 则类似 bash,也需单引号或反引号(`)转义。
- 不要依赖 System.out.println(args[0]) 在 Java 中验证——务必在 Shell 层级先确认参数是否正确传入。可快速验证:
echo 'test23$34' # 输出:test23$34 echo "test23$34" # 输出:test234(若未定义变量 34,则为空)
- Picocli 作为纯 Java 库,完全信任 JVM 传入的 String[] args;它不进行额外的 Shell 式解析,因此无需修改 Picocli 配置或注解。
总结:这不是 Picocli 的 Bug,而是 Shell 字符串处理的通用规则。掌握引号与转义机制,是编写健壮 CLI 工具的基础能力。始终优先在 Shell 层确保参数完整性,再交由 Picocli 安全解析。

















