try {
Process mProcess = Runtime.getRuntime().exec("sh");
DataOutputStream mDataOutputStream = new DataOutputStream(mProcess.getOutputStream());
mDataOutputStream.writeBytes("sh /sdcard/test.sh > /sdcard/run.log \n");
mDataOutputStream.flush();
mDataOutputStream.close();
mProcess.waitFor();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
而此例 /sdcard/test.sh 為:
# cat test.sh
echo "Begin"
date
read something
#while [ 1 ] ;
#do
# echo -n "."
#done
echo "End"
date
上述在 Android app 執行後,可以看到 /sdcard/run.log 顯示:
Begin
Wed Aug 7 21:54:13 CST 2013
End
Wed Aug 7 21:54:13 CST 2013
發現跑起來後,又緊接著關掉,追了很久才發現是 mDataOutputStream.close() 的影響 Orz 比較安全的解法是把 mProcess 和 mDataOutputStream 拉倒 class variable 等級,可隨著物件(此例為 Activity)存在而不被釋放:
public class TestActivity extends Activity {
Process mProcess;
DataOutputStream mDataOutputStream;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
mProcess = Runtime.getRuntime().exec("sh");
mDataOutputStream = new DataOutputStream(mProcess.getOutputStream());
mDataOutputStream.writeBytes("sh /sdcard/test.sh > /sdcard/run.log \n");
mDataOutputStream.flush();
//mDataOutputStream.close();
//mProcess.waitFor();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// …
}
回到對 LOA 的問題,是在於執行 sh 後,再透過 chroot 後就交給一隻 /root/init.sh 處理,而它會等 stdin 的資料,而 mDataOutputStream.close() 的結果就像給予 exit/logout/EOF 的現象,使得 LOA 一直起來後馬上又關掉了。
沒有留言:
張貼留言