簡體   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