ProcessBuilder : 자바에서 외부 프로그램/외부 명령어를 실행할때 사용하는 Class 입니다.
package com.sec.infolink.admin.common.util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
*
* Class Name : CommandExecuteUtil.java
* Description :
*
* Modification Information
* Mod Date Modifier Description
* ---------- ------ ---------------------------
* 2012.11.07 젊은광대 최초생성
*
*
*
* @author 젊은광대
* @since 2012.11.07
* @version 1.0
*/
public class CommandExecuteUtil {
protected final static Log log = LogFactory.getLog(CommandExecuteUtil.class);
public static String executeArr(String[] command, Log log) throws IOException {
ProcessBuilder b = new ProcessBuilder(command);
StringBuffer ret = new StringBuffer();
//표준 에러 출력을 머지 해 출력한다
b.redirectErrorStream(false);
Process p;
p = b.start();
BufferedReader reader = new BufferedReader( new InputStreamReader( p.getInputStream() ) );
String line = null;
//표준 에러 출력이 표준 출력에 머지 해 출력되므로, 표준 출력만 읽어내면 된다
while ((line = reader.readLine()) != null) {
ret.append(line);
}
return ret.toString();
}
public static String execute(String command, String arg1, String arg2) throws IOException {
// sh 파일이나 기타 FullPathTarget 으로 파일을 실행할 수 있다.
// 실행파일 이름만으로 실행이 가능하다.
// 다음과 같은 경우 (실행파일, 옵션, 어규먼트) 형식으로 인식한다.
// 리눅스를 예를 들자면 rm -rf *.sh 형식이라고 이해하면 된다.
// ProcessBuilder builder = new ProcessBuilder("rm -rf *.sh");
// 으로 할 경우 인식을 제대로 못하기 때문에 분리해서 각각 입력한다.
// ProcessBuilder builder = new ProcessBuilder("rm","-rf","*.sh");
ProcessBuilder builder = new ProcessBuilder(command, arg1, arg2);
StringBuffer ret = new StringBuffer();
Process process = null;
try {
// 표준 에러 출력을 머지 해 출력한다
// builder.redirectErrorStream(false);
process = builder.start();
BufferedReader reader = new BufferedReader( new InputStreamReader( process.getInputStream() ) );
// process.waitFor();
// 실행한 프로세스가 종료될 때까지 대기한다.
// 만약 실행한 프로세스가 동기식으로 처리되어야 한다면 사용해야 한다.
// 하지만 그렇지 않다면 사용해서는 안된다.
// 예를 들어 데몬이나 서비스 형태의 프로세스를 실행하고자 하는 상황에서
// 이 명령을 사용하면 해당 프로세스가 종료될 때까지 이 명령을 수행한 프로세스는 진행되지 않는다.
int i = process.waitFor();
if (0 != i){
log.info("Command Execute Fail : << " + i + " >>");
log.debug("builder command : " + builder.command().toString());
} else {
log.debug("builder command : " + builder.command().toString());
}
log.info(process.exitValue());
String line = "";
// 표준 에러 출력이 표준 출력에 머지 해 출력되므로, 표준 출력만 읽어내면 된다
while ((line = reader.readLine()) != null) {
ret.append(line);
}
// process.destroy();
} catch (IOException e) {
log.info(command + " " + "arg1 : " + arg1 + "arg2 : " + arg2);
throw new RuntimeException(e);
} catch (InterruptedException e) {
log.info(command + " " + "" + "");
throw new RuntimeException(e);
} finally {
if ( null != process) {
closeQuietly(process.getInputStream());
closeQuietly(process.getOutputStream());
closeQuietly(process.getErrorStream());
// 해당 프로세스를 종료시킨다.
// 역시 데몬이나 서비스 형태의 프로세스 호출시에는 사용해서는 안된다.
// 호출하면 해당 프로세스는 종료된다.
process.destroy();
} else {
log.info(command + " " + "arg1 : " + arg1 + "arg2 : " + arg2);
log.info("Cannot close Process Streams");
throw new RuntimeException("Cannot close Process Streams");
}
}
return ret.toString();
}
public static void closeQuietly(Writer output) {
try {
if (output != null) {
output.close();
}
} catch (IOException ioe) {
//ignore
}
}
public static void closeQuietly(Reader output) {
try {
if (output != null) {
output.close();
}
} catch (IOException ioe) {
//ignore
}
}
public static void closeQuietly(InputStream output) {
try {
if (output != null) {
output.close();
}
} catch (IOException ioe) {
//ignore
}
}
public static void closeQuietly(OutputStream output) {
try {
if (output != null) {
output.close();
}
} catch (IOException ioe) {
//ignore
}
}
/*
* 실행 예제 : 리눅스와, 윈도우 환경에 따라서 다르게 동작하도록 작업해둡니다.
*/
public static void main(String[] args) {
// OS 구분하여 명령어 처리 - 로컬(window) Dos 작업환경을 위해
String osType = "unix";
if(System.getProperty("os.name").toLowerCase().indexOf("win") >= 0 ){
osType = "window";
}
log.debug("OS check Test : "+System.getProperty("os.name").toLowerCase());
String retail_size = "";
// 윈도우와 리눅스 둘다 동작하도록 작업.
try {
if(osType.equals("window")){
String cmd[] = new String[3];
cmd[0] = "cmd.exe";
cmd[1] = "/C";
cmd[2] = "dir";
retail_size = CommandExecuteUtil.executeArr(cmd, log);
}else{
retail_size =
CommandExecuteUtil.execute(
"rm",
"-rf",
"*.*");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
log.info(retail_size);
}
}
티스토리에서 옮기면서 추가적으로 적자면, 네이버에서는 2가지 방법에 대한 가이드가 있어 참조합니다.