当前位置:   article > 正文

Android上执行shell命令的总结_android 执行shell命令

android 执行shell命令

Android提供了两种执行shell命令的方法。

1.Runtime.getRuntime().exec(cmds)

2.ProcessBuilder(cmds)

两种方法背后的逻辑相同。都是创建一个新的进程,执行shell命令。本文以第一种方法为例。代码如下:

  1. public class RuntimeExcUtil {
  2. public static int run(String[] fCmds){
  3. int tCode=0;
  4. mLogger.i("APP_SHELL", "start run");
  5. try {
  6. Process tProcess = Runtime.getRuntime().exec(fCmds);
  7. printError(tProcess);
  8. tCode = tProcess.waitFor();
  9. mLogger.i("APP_SHELL", "Code Result= "+tCode);
  10. } catch (Exception e) {
  11. mLogger.e("APP_SHELL", "run Failed, Error Message :"+e.getMessage());
  12. }
  13. return tCode;
  14. }
  15. public static int runWithSu(String[] fCmds){
  16. int tCode=0;
  17. mLogger.i("APP_SHELL", "start run");
  18. try {
  19. Process tProcess = Runtime.getRuntime().exec("su");
  20. runShellScript(tProcess,fCmds);
  21. printError(tProcess);
  22. tCode = tProcess.waitFor();
  23. mLogger.i("APP_SHELL", "Code Result= "+tCode);
  24. } catch (Exception e) {
  25. mLogger.e("APP_SHELL", "runWithSu Failed, Error Message :"+e.getMessage());
  26. }
  27. return tCode;
  28. }
  29. private static void printError(Process fProcess){
  30. StringBuilder output = new StringBuilder();
  31. String line;
  32. try(BufferedReader tReader = new BufferedReader(
  33. new InputStreamReader(fProcess.getErrorStream()))) {
  34. while ((line = tReader.readLine()) != null) {
  35. output.append(line).append("\n");
  36. }
  37. if (output.toString().length()>0){
  38. mLogger.e("APP_SHELL", "Error Output = "+output);
  39. }
  40. }catch (Exception e){
  41. mLogger.e("APP_SHELL", "Print Error Output Failed, Error Message :"+e.getMessage());
  42. }
  43. }
  44. private static void runShellScript(Process fProcess, String[] fCmds){
  45. try(DataOutputStream outputStream = new DataOutputStream(fProcess.getOutputStream())) {
  46. for (String tCmd :
  47. fCmds) {
  48. Log.i("APP_SHELL", "Cmd :" + tCmd);
  49. outputStream.writeBytes(tCmd + "\n");
  50. }
  51. outputStream.flush();
  52. outputStream.writeBytes("exit\n");
  53. outputStream.flush();
  54. } catch (Exception e) {
  55. Log.e("APP_SHELL", "Run Shell Script Failed, Error Message :"+e.getMessage());
  56. }
  57. }
  58. }

测试代码如下:

  1. //case 1
  2. RuntimeExcUtil.runWithSu(new String[]{"cp -a -p "+tJavaCrashLogFolderPath+" "+ tCollectFolder});
  3. //case 2
  4. RuntimeExcUtil.runWithSu(new String[]{"cd "+tJavaCrashLogFolderPath,"rm -f crash*"});
  5. //case 3
  6. RuntimeExcUtil.run(new String[]{"cd /sdcard/Download"});
  7. //case 4
  8. RuntimeExcUtil.run(new String[]{"cd", "/sdcard/Download"});
  9. //case 5
  10. RuntimeExcUtil.run(new String[]{"cp -a -p "+tJavaCrashLogFolderPath+" "+ tCollectFolder});
  11. //case 6
  12. RuntimeExcUtil.run(new String[]{"cp", "-a", "-p", tJavaCrashLogFolderPath,tCollectFolder});
  13. //case 7
  14. RuntimeExcUtil.run(new String[]{"rm -f /sdcard/crash/crash*"});
  15. //case 8
  16. RuntimeExcUtil.run(new String[]{"rm", "-f", "/sdcard/crash/crash*"});
Case结果分析
1

结果:执行成功。

原因:创建su窗口,并获取上下文,将后续指令写入

DataOutputStream。不会有权限问题,不会有指令解析问题。

2

结果:同1

原因:同1

3

结果:执行失败。返回Cannot run program "cd /sdcard/Download": error=2, No such file or directory。

原因:将整个命令字符串作为一个参数传递给 RuntimeExcUtil.run() 方法。这个方法可能会将整个字符串解释为一个可执行程序的名称,而不是将其分解为命令和参数。因此,它会尝试去找一个名为 cp -a -p /sdcard/crash/ /destination_folder 的可执行程序。若找不到,则返回No such file or directory。

4

结果:执行失败。返回Cannot run program "cd": error=13, Permission denied。

原因:“cd”是用来改变当前工作目录的 shell 命令,并不是一个可执行程序。所以会得到 "Permission denied" 的错误,这是因为 Android 不允许直接执行这种命令。

5

结果:同3

原因:同3

6

结果:执行成功

原因:将指令与参数分开,方便解析。

7

结果:同3

原因:同3

8

结果:执行成功

原因:将指令与参数分开,方便解析。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/733982
推荐阅读
相关标签
  

闽ICP备14008679号