Bash脚本调用Java解析命令输出时触发NumberFormatException错误
问题与解决
问题描述
我编写了一个Bash脚本,用于读取java -jar bundletool.jar命令的输出。该命令的输出如下:
MIN,MAX 6165350,6228865
我通过head -2 | tail -1跳过第一行,将结果保存到变量output中:
output=$(java -jar bundletool.jar get-size total --apks=$APKS_PATH | head -2 | tail -1)
随后编写了Java文件来分割输出结果:
import java.util.*; public class Demo { public static void main(String[] args) { String[] values = args[0].split(","); System.out.println(Integer.parseInt(values[0])); System.out.println(Integer.parseInt(values[1])); } }
最终的Bash脚本如下:
#!/bin/bash output=$(java -jar bundletool.jar get-size total --apks=$APKS_PATH | head -2 | tail -1) java Demo $output
运行该Bash脚本时,遇到如下错误:
6165350 Exception in thread "main" java.lang.NumberFormatException: For input string: "6228865 at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) at java.base/java.lang.Integer.parseInt(Integer.java:652) at java.base/java.lang.Integer.parseInt(Integer.java:770) at Demo.main(Demo.java:8)
但手动修改output变量为output="6165350,6228865"时,程序能正常运行。
原因分析
问题出在换行符格式上:bundletool.jar的输出可能采用了Windows风格的\r\n(回车+换行),而非Linux/Unix系统默认的\n(仅换行)。当你通过命令捕获输出时,tail -1获取的行末尾带有隐藏的\r控制字符——这个字符肉眼不可见,但会被Java识别为字符串的一部分。
当Java执行Integer.parseInt(values[1])时,实际处理的是"6228865\r",\r属于非数字控制字符,无法被解析为整数,因此抛出NumberFormatException。而你手动赋值的变量不包含这个\r字符,所以能正常解析。
解决方法
提供三种可行的解决思路:
方案1:在Bash中过滤掉\r字符
修改捕获输出的命令,用tr -d '\r'移除所有回车符:
output=$(java -jar bundletool.jar get-size total --apks=$APKS_PATH | head -2 | tail -1 | tr -d '\r')
方案2:在Java代码中清理字符串
对分割后的字符串调用trim()方法,去掉首尾的控制字符和空白:
import java.util.*; public class Demo { public static void main(String[] args) { String[] values = args[0].split(","); System.out.println(Integer.parseInt(values[0].trim())); System.out.println(Integer.parseInt(values[1].trim())); } }
方案3:用awk直接处理第二行
用awk提取第二行并替换掉\r,一步完成处理:
output=$(java -jar bundletool.jar get-size total --apks=$APKS_PATH | awk 'NR==2 {gsub(/\r/,""); print}')
内容的提问来源于stack exchange,提问作者fanjavaid
相关产品推荐
相关产品推荐

