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

私が理解している限り、これはシェル環境がないためです。

次に、必要なコマンドを .sh ファイルに書き込んでから、次のようにコマンドを実行しようとしました。

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

pwd、echo、およびほとんどのコマンドの問題を解決しました。

しかし後で、実行したコマンドの状態を保持したいことに気付きました。たとえば、ディレクトリ( cd data)を変更してコマンドを実行したいmkdir Apoel

そして、ここで私は自分の問題に直面します。何をすべきか?

私は別のアイデアを思いつきました:

シェル スクリプト (.sh) を作成し、ユーザーがコマンドを実行するたびに、その中に新しいコマンドを追加します (そして、ホール スクリプト (.sh) を再度実行します)。しかし、私はそれを行うにはあまり良い方法ではないと思います!

簡単な方法はありますか?私のアプリケーションはターミナルを簡単に開くことができますか?

これはターミナル エミュレータ用に見つけたコードですが、複雑すぎます。

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

4

2 に答える 2

0

まず、いくつかの背景。どの Posix システムでも、シェルには 2 種類のコマンドがあります。

  1. 内部コマンド (pwd、cd、echo)
  2. 外部コマンド (ls、cp、mv、場合によってはエコーも)

すべてのディレクトリ コンテキスト コマンド (cd、pwd など) はシェル内に実装されたコマンドであるため、変更を保持する場合 (たとえば )、シェルを実行し続ける必要がありますcd /data/local/tmp

一方、外部コマンドはスタンドアロンであり、独立して実行できますが、親プロセス (ほとんどの場合、シェル) からディレクトリ コンテキストを取得します。

今すぐ問題を解決します。はい、スクリプトを使用するのは良い考えですが、ファイル編集のオーバーヘッドが必要になるため、実装するのは面倒です。ただし、シェルを使用してオンザフライでスクリプトを作成し、-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) メソッドを使用して追加できます。これにより、コマンド間のディレクトリ コンテキストを維持する可能性があります。しかし、実際にそれを行うにはどうすればよいでしょうか。pwd1 つの解決策は、コマンドに追加し、出力の最後の行を新しいディレクトリ コンテキストとして取得することです。したがって

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 つをアプリに統合するという最後のオプションがあります。

[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 に答える
0

対話型シェルは、stdin から受信した新しいコマンドを待機し、stdout および stderr への出力を生成しながら、実行を継続するシェルです。その結果、変更を含む環境は、セッションの間保持されます。シェルがユーザーにとって有用であるためには、コンソール、シリアルライン、または xterm などを介して、stdin、staud、stderr をユーザーに接続する必要があります。

Android では、通常、作成したシェル プロセスの stdin、stdout、stderr に対応するパイプにフックし、それらを使用して Java プログラムによって提供されるコマンドをプッシュし、プログラムが解釈する出力を受け入れます。画面。

スクリプトを作成して実行するという考えは、すべてのコマンドが実行される前にすべてのコマンドが入力された場合にのみ機能します。

于 2012-04-25T06:54:15.417 に答える