content: package top.niunaijun.blackbox.utils;
  
  import java.io.BufferedReader;
  import java.io.DataOutputStream;
  import java.io.IOException;
  import java.io.InputStreamReader;
  import java.util.List;
  
  public class ShellUtils {
      public static final String COMMAND_SU = "su";
      public static final String COMMAND_SH = "sh";
      public static final String COMMAND_EXIT = "exit\n";
      public static final String COMMAND_LINE_END = "\n";
  
  
      private ShellUtils() {
          throw new AssertionError();
      }
  
  
      /**
       * check whether has root permission
       *
       * @return
       */
      public static boolean checkRootPermission() {
          return execCommand("echo root", true, false).result == 0;
      }
  
  
      /**
       * execute shell command, default return result msg
       *
       * @param command command
       * @param isRoot  whether need to run with root
       * @return
       * @see ShellUtils#execCommand(String[], boolean, boolean)
       */
      public static CommandResult execCommand(String command, boolean isRoot) {
          return execCommand(new String[]{command}, isRoot, true);
      }
  
  
      /**
       * execute shell commands, default return result msg
       *
       * @param commands command list
       * @param isRoot   whether need to run with root
       * @return
       * @see ShellUtils#execCommand(String[], boolean, boolean)
       */
      public static CommandResult execCommand(List<String> commands, boolean isRoot) {
          return execCommand(commands == null ? null : commands.toArray(new String[]{}), isRoot, true);
      }
  
      /**
       * execute shell commands, default return result msg
       *
       * @param commands command array
       * @param isRoot   whether need to run with root
       * @return
       * @see ShellUtils#execCommand(String[], boolean, boolean)
       */
      public static CommandResult execCommand(String[] commands, boolean isRoot) {
          return execCommand(commands, isRoot, true);
      }
  
  
      /**
       * execute shell command
       *
       * @param command         command
       * @param isRoot          whether need to run with root
       * @param isNeedResultMsg whether need result msg
       * @return
       * @see ShellUtils#execCommand(String[], boolean, boolean)
       */
      public static CommandResult execCommand(String command, boolean isRoot, boolean isNeedResultMsg) {
          return execCommand(new String[]{command}, isRoot, isNeedResultMsg);
      }
  
  
      /**
       * execute shell commands
       *
       * @param commands        command list
       * @param isRoot          whether need to run with root
       * @param isNeedResultMsg whether need result msg
       * @return
       * @see ShellUtils#execCommand(String[], boolean, boolean)
       */
      public static CommandResult execCommand(List<String> commands, boolean isRoot, boolean isNeedResultMsg) {
          return execCommand(commands == null ? null : commands.toArray(new String[]{}), isRoot, isNeedResultMsg);
      }
  
      /**
       * execute shell commands
       *
       * @param commands        command array
       * @param isRoot          whether need to run with root
       * @param isNeedResultMsg whether need result msg
       * @return <ul>
       * <li>if isNeedResultMsg is false, {@link CommandResult#successMsg} is null and
       * <li>if {@link CommandResult#result} is -1, there maybe some excepiton.</li>
       * </ul>
       */
      public static CommandResult execCommand(String[] commands, boolean isRoot, boolean isNeedResultMsg) {
          int result = -1;
          if (commands == null || commands.length == 0) {
              return new CommandResult(result, null);
          }
          Process process = null;
          BufferedReader successResult = null;
          StringBuilder successMsg = null;
          DataOutputStream os = null;
          try {
              process = Runtime.getRuntime().exec(isRoot ? COMMAND_SU : COMMAND_SH);
              os = new DataOutputStream(process.getOutputStream());
              for (String command : commands) {
                  if (command == null) {
                      continue;
                  }
                  os.write(command.getBytes());
                  os.writeBytes(COMMAND_LINE_END);
                  os.flush();
              }
              os.writeBytes(COMMAND_EXIT);
              os.flush();
              result = process.waitFor();
              if (isNeedResultMsg) {
                  successMsg = new StringBuilder();
                  successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
                  String s;
                  while ((s = successResult.readLine()) != null) {
                      successMsg.append(s + "\n");
                  }
              }
          } catch (IOException e) {
              e.printStackTrace();
          } catch (Exception e) {
              e.printStackTrace();
          } finally {
              try {
                  if (os != null) {
                      os.close();
                  }
                  if (successResult != null) {
                      successResult.close();
                  }
              } catch (IOException e) {
                  e.printStackTrace();
              }
              if (process != null) {
                  process.destroy();
              }
          }
          return new CommandResult(result, successMsg == null ? null : successMsg.toString());
      }
  
  
      /**
       * result of command
       * <ul>
       * <li>{@link CommandResult#result} means result of command, 0 means normal, else means error, same to excute in
       * linux shell</li>
       * <li>{@link CommandResult#successMsg} means success message of command result</li>
       * </ul>
       *
       * @author <a href="http://www.trinea.cn" target="_blank">Trinea</a> 2013-5-16
       */
      public static class CommandResult {
  
  
          /**
           * result of command
           **/
          public int result;
          /**
           * success message of command result
           **/
          public String successMsg;
  
  
  
          public CommandResult(int result) {
              this.result = result;
          }
  
  
          public CommandResult(int result, String successMsg) {
              this.result = result;
              this.successMsg = successMsg;
          }
      }
  }
  