
PicoCLI 本身不会忽略 $ 符号,问题根源在于 Shell 对命令行参数的变量展开行为;通过单引号包裹或反斜杠转义即可确保 $ 按字面量传递给 Java 应用。
picocli 本身不会忽略 `$` 符号,问题根源在于 shell 对命令行参数的变量展开行为;通过单引号包裹或反斜杠转义即可确保 `$` 按字面量传递给 java 应用。
在使用 PicoCLI 构建命令行工具(如密码加密工具)时,若用户输入的密码包含 $ 符号(例如 "test23$34"),实际传入程序的字符串可能变为 "test234"——这并非 PicoCLI 或 Java 的解析错误,而是Shell(如 bash/zsh)在执行命令前对双引号内 $ 进行了变量展开。
例如,在 bash 中执行:
$ echo "test23$34" test234
Shell 将 $34 解释为第 34 个位置参数(通常为空),因此被替换为空字符串,最终输出 test234。
✅ 正确做法:避免 Shell 展开,确保 $ 作为普通字符传递给 JVM:
-
推荐方式:使用单引号(最安全、最直观)
java -jar encryption.jar passwd-enc -password 'test23$34' -key /user/local/key.txt
单引号内所有字符均按字面量处理,$、\、空格等均不被 Shell 解析。
-
备选方式:在双引号内对 $ 转义
java -jar encryption.jar passwd-enc -password "test23\$34" -key /user/local/key.txt
注意:反斜杠仅在双引号内对 $、`、\ 有效;需确保转义准确(\$),且不要遗漏。
⚠️ 注意事项:
- 不要依赖 PicoCLI 的 @Option(arity = "1..*") 或自定义解析器来“修复”该问题——源头在 Shell,非 Java 层。
- 在脚本中动态拼接命令时,优先使用单引号包裹敏感参数,或通过 printf %q 安全转义:
password='test23$34' cmd=(java -jar encryption.jar passwd-enc -password "$password" -key /user/local/key.txt) "${cmd[@]}" # 安全执行数组命令 - Windows PowerShell/CMD 行为不同(PowerShell 也支持 $ 展开),建议统一使用单引号或反引号(PowerShell 中用 `$)进行转义。
总结:PicoCLI 是一个健壮的 Java 命令行解析库,它忠实地接收 JVM 启动时传入的 String[] args。任何特殊字符丢失,几乎都源于 Shell 的预处理。养成对含 $、*、?、空格等特殊字符的参数使用单引号的习惯,是编写可靠 CLI 工具的基本实践。

















