001package net.gdface.utils; 002 003import java.io.IOException; 004import java.io.InputStream; 005import java.io.InputStreamReader; 006import java.io.LineNumberReader; 007import java.util.ArrayList; 008import java.util.Arrays; 009import java.util.Collections; 010import java.util.List; 011import java.util.logging.Logger; 012 013/** 014 * linux命令行执行器 015 * @author guyadong 016 * 017 */ 018public class CmdExecutor{ 019 private static final Logger logger = Logger.getLogger(CmdExecutor.class.getSimpleName()); 020 private static final String SUDO_CMD = "sudo"; 021 private static final String SHELL_NAME = "/bin/bash"; 022 private static final String SHELL_PARAM = "-c"; 023 private static final String REDIRECT = "2>&1"; 024 /** 执行 sudo 的密ç */ 025 private final String sudoPassword; 026 /** æ˜¯å¦æ˜¾ç¤ºå‘½ä»¤å†…容åŠè¾“出 */ 027 private boolean verbose=true; 028 /** 是å¦é”™è¯¯è¾“出é‡å®šå‘ */ 029 private boolean errRedirect = true; 030 /** 是å¦åŒæ¥ï¼Œä¸»çº¿ç¨‹æ˜¯å¦ç‰å¾…å‘½ä»¤æ‰§è¡Œç»“æŸ */ 031 private boolean sync = true; 032 /** 执行多æ¡å‘½ä»¤æ—¶çš„命令分隔符 */ 033 private String cmdSeparator = " && "; 034 private List<String> cmds = new ArrayList<String>(16); 035 public static CmdExecutor builder(){ 036 return new CmdExecutor(); 037 } 038 public static CmdExecutor builder(String sudoPasword){ 039 return new CmdExecutor(sudoPasword); 040 } 041 protected CmdExecutor(){ 042 this(null); 043 } 044 protected CmdExecutor(String sudoPasword){ 045 this.sudoPassword = sudoPasword; 046 } 047 public CmdExecutor verbose(boolean verbose){ 048 this.verbose = verbose; 049 return this; 050 } 051 public CmdExecutor errRedirect(boolean errRedirect){ 052 this.errRedirect = errRedirect; 053 return this; 054 } 055 public CmdExecutor sync(boolean sync){ 056 this.sync = sync; 057 return this; 058 } 059 public CmdExecutor cmdSeparator(String cmdSeparator){ 060 if(null != cmdSeparator && !cmdSeparator.isEmpty()){ 061 this.cmdSeparator = cmdSeparator; 062 } 063 return this; 064 } 065 private String getRedirect(){ 066 return errRedirect ? REDIRECT : ""; 067 } 068 /** 069 * æ·»åŠ ä¸€æ¡éœ€è¦sudo执行的命令 070 * @param cmd è¦æ‰§è¡Œçš„命令(å—符串ä¸ä¸éœ€è¦æœ‰sudo) 071 * @return 072 */ 073 public CmdExecutor sudoCmd(String cmd){ 074 if(null != cmd && 0 != cmd.length()){ 075 if(null == sudoPassword){ 076 cmds.add(String.format("%s %s %s",SUDO_CMD,cmd,getRedirect())); 077 }else{ 078 cmds.add(String.format("echo '%s' | %s %s %s",sudoPassword,SUDO_CMD,cmd,getRedirect())); 079 } 080 } 081 return this; 082 } 083 /** 084 * æ·»åŠ ä¸€æ¡æ™®é€šå‘½ä»¤ 085 * @param cmd 086 * @return 087 */ 088 public CmdExecutor cmd(String cmd){ 089 if(null != cmd && 0 != cmd.length()){ 090 cmds.add(String.format("%s %s",cmd,getRedirect())); 091 } 092 return this; 093 } 094 private List<String> build(){ 095 return cmds.isEmpty() 096 ? Collections.<String>emptyList() 097 : Arrays.asList(SHELL_NAME,SHELL_PARAM,join(cmds,cmdSeparator)); 098 } 099 private static String join(List<String> strs,String separator) { 100 StringBuffer buffer = new StringBuffer(); 101 for(int i=0;i<strs.size();++i){ 102 if(i>0){ 103 buffer.append(separator); 104 } 105 buffer.append(strs.get(i)); 106 } 107 return buffer.toString(); 108 } 109 /** 110 * å°†{@link InputStream}䏿‰€æœ‰å†…容输出到{@link StringBuffer} 111 * @param in 112 * @return 113 * @throws IOException 114 */ 115 private static void toBuffer(InputStream in,StringBuffer buffer) throws IOException{ 116 if(null == in || null == buffer){ 117 return ; 118 } 119 InputStreamReader ir = new InputStreamReader(in); 120 LineNumberReader input = new LineNumberReader(ir); 121 try{ 122 String line; 123 while ((line = input.readLine()) != null) { 124 buffer.append(line).append("\n"); 125 } 126 }finally{ 127 input.close(); 128 } 129 } 130 /** 131 * 调用{@link Runtime#exec(String[])}执行命令 132 * @return 返回输出结果 133 */ 134 public String exec() throws IOException{ 135 StringBuffer outBuffer = new StringBuffer(); 136 exec(outBuffer,null); 137 return outBuffer.toString(); 138 } 139 /** 140 * 调用{@link Runtime#exec(String[])}执行命令 141 * @param outBuffer æ ‡å‡†è¾“å‡º 142 * @param errBuffer 错误信æ¯è¾“出 143 * @throws IOException 144 */ 145 public void exec(StringBuffer outBuffer,StringBuffer errBuffer) throws IOException{ 146 List<String> cmdlist = build(); 147 if(!cmdlist.isEmpty()){ 148 if(verbose){ 149 logger.info(join(cmdlist," ")); 150 } 151 Process process = Runtime.getRuntime().exec(cmdlist.toArray(new String[cmdlist.size()])); 152 if(sync){ 153 try { 154 process.waitFor(); 155 } catch (InterruptedException e) { 156 } 157 } 158 toBuffer(process.getInputStream(),outBuffer); 159 toBuffer(process.getErrorStream(),errBuffer); 160 } 161 } 162}