繁体   English   中英

如何以编程方式在 android 中执行所有可能的 unix(shell) 命令?

[英]How can I execute all the possible unix(shell) commands in android programmatically?

我有这个 .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

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

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

所有目录上下文命令(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.File%29

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

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

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

暂无
暂无

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

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