1

我有这个 .php 文件向我的 android 应用程序发送命令:

在此处输入图像描述

我尝试过使用:

Runtime.getRuntime().exec(commandLine);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));

但是命令 echo、pwd 和其他一些命令不起作用。

我得到以下异常:

java.io.IOException: Error running exec(). Command: [pwd] Working Directory: null Environment: null

据我了解,这是因为没有任何 shell 环境。

然后我尝试在 .sh 文件中写入我想要的命令,然后以这种方式执行命令:

Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("sh /runCmds/shTest.sh");
InputStream is = proc.getInputStream();

并通过 pwd、echo 和大多数命令解决了问题。

但后来我意识到我想保持我执行的命令的状态。例如我想改变目录(cd data)并执行命令mkdir Apoel

这就是我面临问题的时候。该怎么办?

我想出了另一个主意:

制作一个 shell 脚本(.sh),每次用户想要执行命令时,都在其中添加新命令(并再次运行漏洞脚本(.sh))。但我认为这不是一个很好的方法!

有什么简单的方法吗?我的应用程序可以轻松打开终端吗?

这是我为终端仿真器找到的代码,但它太复杂了!

https://github.com/jackpal/Android-Terminal-Emulator

4

2 回答 2

0

交互式 shell 一直在运行,等待从 stdin 接收到的新命令,同时将其输出到 stdout 和 stderr - 因此,它的环境(包括任何更改)在会话期间保留。为了使 shell 对用户有用,stdin、stoud、stderr 需要通过控制台、串行线或 xterm 等连接到用户。

在 Android 上,通常您所做的是将与您创建的 shell 进程的 stdin、stdout、stderr 对应的管道挂钩,并使用它们来推送您的 java 程序提供的命令并接受您的程序的输出来解释/展示。

创建脚本并运行它的想法仅适用于在执行任何命令之前输入所有命令的情况。

于 2012-04-25T06:54:15.417 回答
0

首先,一些背景。在任何 Posix 系统上,在 shell 中,有两种类型的命令:

  1. 内部命令 (pwd,cd,echo)
  2. 外部命令(ls、cp、mv,有时还有 echo)

所有目录上下文命令(cd、pwd 等)都是在 shell 内实现的命令,因此如果要保留更改(例如,cd /data/local/tmp),则需要 shell 保持运行。

另一方面,外部命令是独立的,可以独立运行,但从它们的父进程(大多数情况下,shell)获取它们的目录上下文。

现在来解决问题。是的,使用脚本是个好主意,但实施起来很痛苦,因为它需要文件编辑的开销。但是,我们可以使用 shell 动态创建脚本并使用-c选项执行它。例如:

/system/bin/sh -c 'cd /data/local/tmp; touch abc; cp abc def; cd /; rm /data/local/tmp/abc'

在夏天:

String sPrefix="/system/bin/sh -c 'cd someplace;";
String sInputCmd=getCommand(); // this is simulating your command input
String sPostfix="'";

Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(sPrefix+sInputCmd+sPostfix); // sh -c 'cd someplace; echo do something'
InputStream is = proc.getInputStream();

然而,这并没有给我们设置目录上下文的能力,所以我们需要模拟它。可以使用 Runtime.exec(String command, String[] envp, File dir) 方法添加目录上下文。有了这个,我们就有可能在命令之间维护目录上下文。但我们实际上如何做到这一点?一种解决方案是附加pwd到命令并将输出的最后一行作为新的目录上下文。因此

String sPath = "/"; // start in root directory
String sPrefix = "/system/bin/sh -c 'cd someplace;";
String sInputCmd; // this is simulating your command input
String sPostfix = ";echo;pwd'";
Runtime rt = Runtime.getRuntime();
while(!(sInputCmd=getCommand()).equals("")) {
    File dir= new File(sPath);
    Process proc = rt.exec(sPrefix+sInputCmd+sPostfix, NULL, dir);
    InputStream is = proc.getInputStream();
    // Do processing on input.
    sPath= last_line_of_is ;
}

最后,最后一个选项是将其中一个终端仿真器集成到您的应用程序中。

[1] http://docs.oracle.com/javase/6/docs/api/java/lang/Runtime.html#exec%28java.lang.String,%20java.lang.String%5B%5D,%20java .io.文件%29

于 2012-04-25T06:28:21.270 回答