You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何同一条root权限的logcat+grep命令在终端可用但APP中生成空文件?

问题排查与解决方案

嘿,这个问题我之前做类似工具的时候也踩过坑,咱们来聊聊问题出在哪以及怎么解决~

核心原因

你在终端模拟器里能正常执行,是因为终端本身就是一个交互式的shell环境,它会自动解析命令里的管道(|)和重定向(>)这些特殊符号。但在APP里直接通过Runtime.exec("su")然后写命令的时候,默认情况下su并不会启动完整的shell来处理这些元字符——它只会把你写入的内容当作单个命令执行,根本没识别到|是管道,自然也就不会调用grep来筛选内容,最后生成的文件当然是空的。

而不带grep的logcat > 文件能生效,是因为部分设备的su实现会处理简单的重定向符号,但管道这种需要多进程协作的操作,必须依赖shell来解析才行。

解决办法

核心思路就是让su通过shell来执行整个命令,让shell帮我们解析管道和重定向。这里有两种实现方式:

方式1:直接用su的-c参数

su的-c参数可以让它直接调用shell执行指定的命令字符串,这样整个带管道的命令会被shell正确解析:

try {
    // 注意Java字符串里的双引号需要用\\转义
    Process p = Runtime.getRuntime().exec("su -c \"logcat | grep --line-buffered \\\"search string\\\" > /storage/emulated/0/logcat.log\"");
    // 如果需要等待命令执行完成(比如非持续输出场景),可以加上waitFor()
    // p.waitFor();
} catch (IOException | InterruptedException e) {
    e.printStackTrace();
}

方式2:在su内部调用sh来执行命令

如果有些设备的su对-c参数支持不好,也可以在su之后手动启动sh来处理命令:

try {
    Process p = Runtime.getRuntime().exec("su");
    DataOutputStream dos = new DataOutputStream(p.getOutputStream());
    // 用sh -c包裹整个命令,让shell解析管道和重定向
    dos.writeBytes("sh -c \"logcat | grep --line-buffered \\\"search string\\\" > /storage/emulated/0/logcat.log\"\n");
    dos.flush();
    dos.close();
    // p.waitFor();
} catch (IOException | InterruptedException e) {
    e.printStackTrace();
}

额外排查小技巧

如果还是有问题,可以试试这两个小方法:

  • 用grep的绝对路径:有些设备上grep可能在/system/bin/grep,把命令里的grep改成/system/bin/grep,避免找不到命令的问题。
  • 重定向错误输出:在命令末尾加上2>&1,把错误信息也写入日志文件,比如:
    su -c "logcat | grep --line-buffered \"search string\" > /storage/emulated/0/logcat.log 2>&1"
    
    这样如果grep或者logcat有错误,就能在日志里看到具体问题了。

内容的提问来源于stack exchange,提问作者1nikolas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:11:30