[英]Android - Interactive shell (Runtime.getRuntime().exec())
How to run an interactive shell on android? 如何在Android上运行交互式Shell? (rooted device)
(根设备)
I need the nexts steps: 我需要接下来的步骤:
1 - Execute shell process (onCreate) 1-执行外壳程序(onCreate)
Process p = Runtime.getRuntime().exec(String[]{"su","-c","sh"});
2 - Get the output (onCreate) 2-获取输出(onCreate)
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream));
//dos is a field (a class attribute)
dos = new DataOutputStream(p.getOutputStream());
new Thread(new Runnable() {
@Override
public void run() {
String l;
//wait the console output and write it
while((l = br.readLine()) != null) {
Log.v("info", l);
}
}
}).start();
3 - Execute a command (Button -> onClick()) 3-执行命令(按钮-> onClick())
cmd("wpa_cli");
The cmd method is: cmd方法是:
public void cmd(String cmd) {
dos.writeBytes(cmd + "\n");
dos.flush();
}
The Log never shows the console output. 日志从不显示控制台输出。
Next step: 下一步:
4 - Get the output of a subcommand of wpa_cli (another Button -> onClick()) 4-获取wpa_cli子命令的输出(另一个Button-> onClick())
cmd("help");
Should show the wpa_cli help but it doesn't work. 应该显示wpa_cli帮助,但不起作用。
If i press the button many times appears incomplete output (help) 如果我多次按该按钮,则显示的输出不完整(帮助)
What is the correct way to initialize a process when the Activity is creating and keep it active to interact? 创建活动并保持活动状态以进行交互时,初始化过程的正确方法是什么?
Thanks. 谢谢。
PostData 发布数据
I replaced the line Log.v("info", l);
我替换了
Log.v("info", l);
with 同
fos.write(l);
Message msg = handlerTest.obtainMessage();
msg.obj = l;
handlerTest.sendMessage(msg);
fos -> FileOutputStream object fos-> FileOutputStream对象
Handler handlerTest = new Handler() {
@Override
handleMessage(Message msg) {
if (msg != null) {
//alert... (String)msg.obj;
}
}
};
And only displays the alert from the direct commands, as help
for example. 并且仅显示直接命令中的警报,例如
help
。 The command status
only work when the stream is closed. 命令
status
仅在流关闭时起作用。 (after execute cmd("quit");
and cmd("exit");
) (在执行
cmd("quit");
和cmd("exit");
)
I don't understand. 我不明白 stdout is more that one?
标准输出不止一个? I can interact with the output without close the stream?
我可以在不关闭流的情况下与输出交互吗?
With adb shell
i read the output file (created after closing the stream) and it's complete. 使用
adb shell
我读取了输出文件(在关闭流之后创建),并且文件已完成。
PostData2: PostData2:
The problem is the buffer. 问题是缓冲区。 Between the binary file (executed) output and java process i can disable the buffer without using Native I/O?
在二进制文件(已执行)输出和Java进程之间,我可以不使用本机I / O禁用缓冲区吗? The Android Terminal Emulator works fine, it's using NIO?
Android Terminal Emulator工作正常,是否正在使用NIO?
Solution by OP. 由OP解决。
Without using the tool stdbuf
(of coreutils) in Android I found the next solution: 在不使用Android中(coreutils的)
stdbuf
工具的情况下,我找到了下一个解决方案:
I'm using two processes called process1 and process2: both -> new ProcessBuilder(new String[]{"su", "-c", "sh"}).start();
我正在使用两个名为process1和process2的进程:都->
new ProcessBuilder(new String[]{"su", "-c", "sh"}).start();
In the first process I run wpa_cli
在第一个过程中,我运行
wpa_cli
dos1.write("wpa_cli".getBytes());
dos1.flush();
In a thread I wait 5 seconds and run wpa_cli in the second process. 在线程中,我等待5秒钟,然后在第二个进程中运行wpa_cli。
dos2.write("wpa_cli".getBytes());
dos2.flush();
To get the output from wpa_cli is necessary to close it with quit
要从wpa_cli获取输出,必须通过
quit
将其关闭
dos1.write("quit".getBytes());
dos1.flush();
The main thread that work with both processes: 适用于这两个进程的主线程:
new Thread(new Runnable() {
@Override
public void run() {
boolean firstProcess = true;
while (follow) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (follow) {
if (firstProcess) {
cmd("wpa_cli", dos2);
cmd("quit", dos1);
} else {
cmd("wpa_cli", dos1);
cmd("quit", dos2);
}
firstProcess = !firstProcess;
}
}
}
}).start();
Important : Both processes have this (when the process is created): 重要说明 :这两个过程都具有此功能(在创建过程时):
new Thread(new Runnable() {
@Override
public void run() {
BufferedReader br = new BufferedReader(new InputStreamReader(process1.getInputStream()));
String l;
try {
Message msg;
while ((l = br.readLine()) != null) {
msg = handlerStdout.obtainMessage();
msg.obj = l;
handlerStdout.sendMessage(msg);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
The handler handlerStdout
does the desired job. 处理程序
handlerStdout
完成了所需的工作。 It receives the output of wpa_cli
every 5 seconds: the output comes from process1 and process2 alternatively 它每5秒接收一次
wpa_cli
的输出:输出交替来自process1和process2
An alternative solution would be to compile coreutils or stdbuf
for Android. 另一种解决方案是为Android编译coreutils或
stdbuf
。 Or install compiled coreutils from http://forum.xda-developers.com/showthread.php?t=2613243 (for me not work stdbuf
because the libstdbuf.so
not found) 或从http://forum.xda-developers.com/showthread.php?t=2613243安装编译的coreutils(对我
stdbuf
, libstdbuf.so
stdbuf
因为libstdbuf.so
)
With stdbuf -oL wpa_cli
the output isn't buffered (buffer one line). 使用
stdbuf -oL wpa_cli
,输出不会被缓冲(缓冲一行)。 Without it the output is buffered (4k). 没有它,输出将被缓冲(4k)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.