为什么相同的命令在终端中有效,但在我的应用程序中却无效?
Why does the same command work in a terminal but not in my app?
我正在制作一个应用程序,它使用 root,需要一个 logcat 以便它可以在另一个应用程序上找到特定的错误。对我来说最简单的方法是直接从命令中将 logcat 保存到文件中。所以我要做的就是 运行 su
然后 logcat | grep --line-buffered "search string" > /path/to/save/logcat.log
。当我在终端仿真器上 运行(如 this or even 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();
}
我将我的评论列为答案,因为这显然有助于解决您的问题,但这里还有更多我无法完全解决的问题:
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.
所以
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 处理对 TTY(终端仿真)与非 TTY(您的程序)敏感,并且具有不同的缓冲方法(TTY 中的行缓冲,否则完全缓冲)。我意识到您的 grep 选项应该可以解决这个问题。 TTY 与非 TTY 之间的这种差异可以解释问题的根源。
- 发布的代码正在向创建的进程发送命令 (logcat...) 并继续。因此,例如,如果 logcat 输出大量数据,理论上您发布的代码将继续并离开范围 - 当
p
超出范围时创建的进程会发生什么 - 不确定。
无论如何,很高兴您能够继续。
我正在制作一个应用程序,它使用 root,需要一个 logcat 以便它可以在另一个应用程序上找到特定的错误。对我来说最简单的方法是直接从命令中将 logcat 保存到文件中。所以我要做的就是 运行 su
然后 logcat | grep --line-buffered "search string" > /path/to/save/logcat.log
。当我在终端仿真器上 运行(如 this or even 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();
}
我将我的评论列为答案,因为这显然有助于解决您的问题,但这里还有更多我无法完全解决的问题:
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.
所以
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 处理对 TTY(终端仿真)与非 TTY(您的程序)敏感,并且具有不同的缓冲方法(TTY 中的行缓冲,否则完全缓冲)。我意识到您的 grep 选项应该可以解决这个问题。 TTY 与非 TTY 之间的这种差异可以解释问题的根源。
- 发布的代码正在向创建的进程发送命令 (logcat...) 并继续。因此,例如,如果 logcat 输出大量数据,理论上您发布的代码将继续并离开范围 - 当
p
超出范围时创建的进程会发生什么 - 不确定。
无论如何,很高兴您能够继续。