Android-交互式外壳程序(Runtime.getRuntime()。exec()) [英] Android - Interactive shell (Runtime.getRuntime().exec())

查看:294
本文介绍了Android-交互式外壳程序(Runtime.getRuntime()。exec())的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在android上运行交互式shell? (有根设备)

How to run an interactive shell on android? (rooted device)

我需要执行以下步骤:

1-执行shell进程(onCreate)

1 - Execute shell process (onCreate)

Process p = Runtime.getRuntime().exec(String[]{"su","-c","sh"});

2-获取输出(onCreate)

2 - Get the output (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-执行命令(按钮-> onClick())

3 - Execute a command (Button -> onClick())

cmd("wpa_cli");

cmd方法为:

public void cmd(String cmd) {
   dos.writeBytes(cmd + "\n");
   dos.flush();
}

日志从不显示控制台输出。

The Log never shows the console output.

下一步:

4-获取wpa_cli子命令的输出(另一个Button-> onClick())

4 - Get the output of a subcommand of wpa_cli (another Button -> onClick())

cmd("help");

应显示wpa_cli帮助,但不起作用。

如果我多次按下按钮会出现不完整的输出(帮助)

Should show the wpa_cli help but it doesn't work.
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?

谢谢。

PostData

我替换行 Log .v( info,l);


PostData
I replaced the line Log.v("info", l);
with

fos.write(l);
Message msg = handlerTest.obtainMessage();
msg.obj = l;
handlerTest.sendMessage(msg);

fos-> FileOutputStream对象

fos -> FileOutputStream object

Handler handlerTest = new Handler() {
    @Override
    handleMessage(Message msg) {
       if (msg != null) {
         //alert... (String)msg.obj;
       }
    }
}; 

仅显示直接命令的警报,如 help 。命令 status 仅在流关闭时有效。 (执行 cmd( quit); cmd( exit);

And only displays the alert from the direct commands, as help for example. The command status only work when the stream is closed. (after execute cmd("quit"); and cmd("exit");)

我不明白。标准输出不止一个?我可以不关闭流而与输出交互吗?

I don't understand. stdout is more that one? I can interact with the output without close the stream?

使用 adb shell 我读取了输出文件(创建后

With adb shell i read the output file (created after closing the stream) and it's complete.

PostData2:

PostData2:

问题是缓冲区。在二进制文件(已执行)输出和Java进程之间,我可以不使用本机I / O禁用缓冲区吗?
Android终端仿真器可以很好地运行,它正在使用NIO吗?

The problem is the buffer. Between the binary file (executed) output and java process i can disable the buffer without using Native I/O? The Android Terminal Emulator works fine, it's using NIO?

推荐答案

OP解决方案。

不使用Android中(coreutils的) stdbuf 工具,我找到了下一个解决方案:

Without using the tool stdbuf (of coreutils) in Android I found the next solution:

我正在使用两个名为process1和process2的过程:两者-> new ProcessBuilder(new String [] { su, -c, sh })。start();

I'm using two processes called process1 and process2: both -> new ProcessBuilder(new String[]{"su", "-c", "sh"}).start();

在第一个过程中,我运行 wpa_cli

In the first process I run wpa_cli

dos1.write("wpa_cli".getBytes());
dos1.flush();

在线程中,我等待5秒,然后在第二个进程中运行wpa_cli。

In a thread I wait 5 seconds and run wpa_cli in the second process.

dos2.write("wpa_cli".getBytes());
dos2.flush();

要从wpa_cli获取输出,必须在 quit处关闭

To get the output from wpa_cli is necessary to close it with 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();

处理程序 handlerStdout 完成所需的工作。它每5秒接收一次 wpa_cli 的输出:输出交替来自process1和process2

The handler handlerStdout does the desired job. It receives the output of wpa_cli every 5 seconds: the output comes from process1 and process2 alternatively

另一种解决方案是为Android编译coreutils或 stdbuf 。或从 http://forum.xda-developers.com/showthread安装编译过的coreutils .php?t = 2613243 (对我来说, stdbuf 不起作用,因为未找到 libstdbuf.so

An alternative solution would be to compile coreutils or stdbuf for Android. 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)

使用 stdbuf -oL wpa_cli 不会缓冲输出(缓冲一行)。没有它,输出将被缓冲(4k)。

With stdbuf -oL wpa_cli the output isn't buffered (buffer one line). Without it the output is buffered (4k).

这篇关于Android-交互式外壳程序(Runtime.getRuntime()。exec())的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆