简体   繁体   English

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

[英]Why does the same command work in a terminal but not in my app?

I'm making an app which, using root, takes a logcat so it can find a certain error on another app. 我正在开发一个使用root的logcat,以便可以在另一个应用程序上找到某个错误的应用程序。 The easiest approach for me is saving the logcat to a file directly from the command. 对我而言,最简单的方法是直接从命令将logcat保存到文件。 So all I have to do is run su and then logcat | grep --line-buffered "search string" > /path/to/save/logcat.log 因此,我要做的就是先运行su ,然后运行logcat | grep --line-buffered "search string" > /path/to/save/logcat.log logcat | grep --line-buffered "search string" > /path/to/save/logcat.log . logcat | grep --line-buffered "search string" > /path/to/save/logcat.log When I run this on a terminal emulator (like this or even this ), it saves the output to a file just exactly how I want it to do so. 当我在终端仿真器(如this或什至this )上运行此命令时,它将输出完全按照我想要的方式保存到文件中。 But when I run the exact same command from my app, it gets me a blank file. 但是,当我从应用程序中运行完全相同的命令时,它将获得一个空白文件。 I've tried many different ways to output the logcat but they all get me an empty file. 我尝试了多种输出logcat的方法,但它们都给我一个空文件。 Interestingly, when I take a normal logcat using the app (without grep, using ">" to output), the file is being saved as it should and it contains the string I want to grep. 有趣的是,当我使用该应用程序获取普通logcat时(不使用grep,使用“>”输出),该文件将按原样保存,并且包含我要grep的字符串。 What am I doing wrong? 我究竟做错了什么?

Here is the code I use: 这是我使用的代码:

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();
 }

I'm listing my comment as an answer since that evidently helped solve your issue but there is more going on here which I'm not capable of fully addressing: 我将我的评论列为答案,因为这显然有助于解决您的问题,但是这里还有更多我无法完全解决的问题:

Try redirecting stderr as well to see if there is any error which can then be captured - I think that would be &> (that's bash) - and >outfile 2>&1 for more general syntax. 尝试重定向stderr,以查看是否存在任何可以捕获的错误-我认为这是&>(那是bash)-和> outfile 2>&1,以获得更通用的语法。

So 所以

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

Or 要么

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

The original intention of the comment was to get you more information as to what was really going on - as it turns out, it helped you get the result you were looking for. 该评论的初衷是为您提供有关实际情况的更多信息-事实证明,它有助于您获得所需的结果。

I believe there are a few factors at work here which may contribute to why adding stderr helped: 我相信这里有一些因素在起作用,这可能有助于添加stderr的原因:

  • stderr (which the comment suggested adding) is non-buffered - I think (but can't prove) the non-buffering is what is helping you even though the output being captured is stdout. stderr(建议在注释中添加)是非缓冲的-我认为(但不能证明)即使捕获的输出是stdout,非缓冲也可以为您提供帮助。
  • stdout processing is sensitive to TTY (terminal emulation) vs non-TTY (your program) and has different buffering approaches (line buffering in TTY otherwise fully buffered). stdout处理对TTY(终端仿真)与非TTY(您的程序)比较敏感,并且具有不同的缓冲方法(在TTY中进行行缓冲,否则完全缓冲)。 I realize your grep option should overcome this. 我意识到您的grep选项应该可以克服这个问题。 This difference in TTY-nonTTY may explain the source of your problem. TTY-nonTTY的这种差异可能解释了问题的根源。
  • The code posted is sending a command (logcat...) to the process created and continuing . 发布的代码正在向创建的进程发送命令(logcat ...) 并继续 So for example if the logcat were to output lots of data, in theory your posted code would continue and leave scope - what happens to the process created when p is out scope - not sure. 因此,例如,如果logcat将输出大量数据,则理论上您发布的代码将继续并离开作用域-当p超出作用域时所创建的过程会发生什么-不确定。

Anyways, glad you were able to proceed. 无论如何,很高兴您能够继续。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM