简体   繁体   English

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

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

I have this .php file sending commands to my android application:我有这个 .php 文件向我的 android 应用程序发送命令:

在此处输入图片说明

I have tried working with:我曾尝试与:

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

but the commands echo, pwd and some others are not working.但是命令 echo、pwd 和其他一些命令不起作用。

I get the following exception:我收到以下异常:

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

As far as I understand this is because there is not any shell environment.据我了解这是因为没有任何shell环境。

Then I have tried writing in a .sh file the command I want and then execute the command this way:然后我尝试在 .sh 文件中写入我想要的命令,然后以这种方式执行命令:

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

and got solved the problem with pwd, echo and most of the commands.并通过 pwd、echo 和大多数命令解决了问题。

But later on I realized that I want to keep the state of the commands I execute.但后来我意识到我想保持我执行的命令的状态。 For example I want to change directory( cd data ) and execute the command mkdir Apoel例如我想更改目录( cd data )并执行命令mkdir Apoel

And here is when I face my problem.这是我面临问题的时候。 What to do?该怎么办?

I came up with another idea:我想到了另一个想法:

Make a shell script (.sh) and each time the user wants to execute a command append the new command in it (and run the hole script(.sh) again).制作一个 shell 脚本 (.sh),每次用户想要执行一个命令时,在其中添加新命令(并再次运行孔脚本(.sh))。 But I think is not a very good way to do it!但是我觉得不是一个很好的方法呢!

Is there any easy way to it?有什么简单的方法吗? Can my application open a terminal easily?我的应用程序可以轻松打开终端吗?

Here is a code I found for a Terminal Emulator, but it is too complicated!这是我为终端模拟器找到的代码,但它太复杂了!

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

First, some background.首先,一些背景。 On any Posix system, in the shell, there are 2 types of commands:在任何 Posix 系统上,在 shell 中,有两种类型的命令:

  1. Internal commands (pwd,cd,echo)内部命令(pwd、cd、echo)
  2. external commands (ls,cp,mv, sometimes echo as well)外部命令(ls、cp、mv,有时也回显)

All the directory context commands (cd,pwd etc) are commands implemented inside the shell and thus require the shell to remain running, if the changes are to hold (for eg. cd /data/local/tmp ).所有目录上下文命令(cd、pwd 等)都是在 shell 内部实现的命令,因此如果要保持更改(例如cd /data/local/tmp ),则需要 shell 保持运行。

On the other hand, external commands are standalone and can run indepenedently, but acquire their directory context from their parent process (in most cases, the shell).另一方面,外部命令是独立的,可以独立运行,但从它们的父进程(在大多数情况下,shell)获取它们的目录上下文。

Now to solve the problem.现在来解决问题。 Yes, using a script is a good idea, but it is painful to implement, as it requires an overhead of file editing.是的,使用脚本是个好主意,但实施起来很痛苦,因为它需要文件编辑的开销。 However, we can use the shell to create a script on the fly and execute it using the -c option.但是,我们可以使用 shell 动态创建脚本并使用-c选项执行它。 For example:例如:

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

In summery:在夏天:

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();

However, this does not give us the capability to set a directory context, so we need to simulate that.然而,这并没有给我们设置目录上下文的能力,所以我们需要模拟它。 Directory contexts can be added by using the Runtime.exec(String command, String[] envp, File dir) method.可以使用 Runtime.exec(String command, String[] envp, File dir) 方法添加目录上下文。 With this we have the possibility of maintaining directory context between commands.有了这个,我们就有可能在命令之间维护目录上下文。 But how do we actually do that?但我们实际上如何做到这一点? One solution is to append pwd to the command and take the last line of the output as the new directory context.一种解决方案是将pwd附加到命令并将输出的最后一行作为新的目录上下文。 Thus因此

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 ;
}

Finally, the last option is to integrate one of the terminal emulators into you app.最后,最后一个选项是将一个终端模拟器集成到您的应用程序中。

[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 [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

An interactive shell is one which remains running, waiting for new commands which it receives from stdin, while producing it's output to stdout and stderr - as a result, it's environment including any changes is retained for the duration of the session.交互式 shell 保持运行状态,等待从 stdin 接收到的新命令,同时将其输出生成到 stdout 和 stderr - 因此,在会话期间保留其环境,包括任何更改。 For the shell to be useful to a user, stdin, stoud, stderr need to be connected through to the user - via the console, a serial line, or xterm, etc.要使 shell 对用户有用,stdin、stoud、stderr 需要通过控制台、串行线或 xterm 等连接到用户。

On Android, typically what you do is hook onto the pipes corresponding to stdin, stdout, stderr for the shell process that you've created, and use them to push in commands provided by your java program and accept output for your program to interpret/display.在 Android 上,通常您所做的是挂钩与您创建的 shell 进程的 stdin、stdout、stderr 对应的管道,并使用它们来推送您的 java 程序提供的命令并接受您的程序的输出以进行解释/展示。

The idea of creating a script and running it would only work in the case where all the commands are entered before any of them execute.创建脚本并运行它的想法仅适用于在执行任何命令之前输入所有命令的情况。

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

相关问题 如何以编程方式在 android 中使用 blktrace 命令执行 shell 脚本? - How to execute shell scripts with blktrace commands in android programmatically? 如何在Android中执行Shell命令? - How to execute shell commands in android? 如何在Android中以编程方式执行终端命令 - How to execute terminal commands programmatically in android 如何在Android中以编程方式执行ADB命令 - How to execute adb commands programmatically in android 在Android中以编程方式执行shell命令 - executing shell commands programmatically in Android Android联系人-如何以编程方式查找所有可能的帐户类型和名称 - Android Contacts - How can I programmatically find all possible account types & names 如何以编程方式在android上执行* .sql脚本? - How can I execute a *.sql script on android programmatically? 如何在Android设备的Mac OS上以Java编程方式执行ADB命令 - How to execute ADB commands programmatically in Java on Mac OS for Android device 是否可以从应用程序执行ADB shell命令? - Is it possible to execute ADB shell commands from app? 如何从Shell获取有关Android Shell中可用命令的信息? - How can I get information from the shell about commands available in Android shell?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM