为什么相同的命令在终端中起作用但在我的应用程序中不起作用?

时间:2019-01-30 15:53:57

标签: java android logcat

我正在开发一个应用程序,该应用程序使用root用户使用logcat,以便可以在另一个应用程序上找到某个错误。对我而言,最简单的方法是直接从命令将logcat保存到文件。因此,我要做的就是先运行su,然后运行logcat | grep --line-buffered "search string" > /path/to/save/logcat.log。当我在终端仿真器(例如this或什至this)上运行此命令时,它会将输出完全按照我想要的方式保存到文件中。但是,当我从应用程序中运行完全相同的命令时,它将获得一个空白文件。我尝试了多种输出logcat的方法,但它们都给我一个空文件。有趣的是,当我使用该应用程序获取普通logcat时(不使用grep,使用“>”输出),该文件将按原样保存,并且包含我要grep的字符串。我在做什么错了?

这是我使用的代码:

try {
        Process p = Runtime.getRuntime().exec("su");
        DataOutputStream dos = new DataOutputStream(p.getOutputStream());
        dos.writeBytes("logcat | grep --line-buffered \"search string\" > /storage/emulated/0/logcat.log\n");
        dos.flush();
 } catch (IOException e) {
     e.printStackTrace();
 }

1 个答案:

答案 0 :(得分:0)

我将我的评论列为答案,因为这显然有助于解决您的问题,但是这里还有更多我无法完全解决的问题:

  

也尝试重定向stderr,以查看是否存在任何可以捕获的错误-我认为这是&>(那是bash)-和> outfile 2>&1,以获得更通用的语法。

所以

dos.writeBytes("logcat | grep --line-buffered \"search string\" &> /storage/emulated/0/logcat.log\n");

dos.writeBytes("logcat | grep --line-buffered \"search string\" > /storage/emulated/0/logcat.log 2>&1\n");

该评论的初衷是为您提供有关实际情况的更多信息-事实证明,它有助于您获得所需的结果。

我相信这里有一些因素在起作用,这可能有助于添加stderr的原因:

  • stderr(建议在注释中添加)是非缓冲的-我认为(但不能证明)即使在捕获的输出是stdout的情况下,非缓冲也是有帮助的。
  • stdout处理对TTY(终端仿真)与非TTY(您的程序)比较敏感,并且具有不同的缓冲方法(在TTY中进行行缓冲,否则完全缓冲)。我意识到您的grep选项应该可以克服这个问题。 TTY-nonTTY的这种差异可能解释了问题的根源。
  • 发布的代码正在向创建的进程发送命令(logcat ...),并继续。因此,例如,如果logcat将输出大量数据,则理论上您发布的代码将继续并离开范围-p超出范围时创建的过程会发生什么-不知道。

无论如何,很高兴您能够继续。