1. 개요
자바에서 시스템 명령어(ping, ll 등)를 실행할 수 있는 도구를 찾아보았는데, ProcessBuilder라는 것을 알게되었다.
참고로 필자는 리눅스 명령어를 기반으로 다루겠다.
윈도우나 다른 OS의 경우 해당 OS 명령어로 변경해서 적용할 수 있다.
그럼 이제 ProcessBuilder 사용 방법에 대해서 정리해보자.
2. ProcessBuilder란?
ProcessBulder는 자바에서 시스템 명령어나 스크립트를 실행할 수 있으며, 다양한 프로세스의 입출력을 관리할 수 있는 클래스이다. 외부 디펜던시를 추가할 필요없이 java.lang 패키지에 포함되어 있다.
특징 및 기능으로 4가지로 정리할 수 있다.
- 시스템 명령어 실행(ping, ll, mkdir 등)
- 프로세스 실행환경 설정
- 외부 프로세스의 표준 입력/출력/오류 처리
- 비동기적인 프로세스 실행 및 종료 대기
3. ProcessBuilder 사용방법
a. 시스템 명령어 실행
- 시스템 명령어인 ping을 실행하여 결과를 확인할 수 있다.
String command = "ping -c 4 www.google.com"
// ProcessBuilder processBuilder = new ProcessBuilder(command.split(" ")); // 생성자를 통해서 command 주입이 가능하다.
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command("ping", "-c", "4", "www.google.com");
try {
Process process = processBuilder.start();
int exitCode = process.waitFor();
if (exitCode == 0) {
System.out.println("프로세스가 성공적으로 종료되었습니다.");
} else {
System.out.println("프로세스가 실패했습니다. 종료 코드: " + exitCode);
}
} catch (Exception e) {
e.printStackTrace();
}
b. 프로세스 실행환경 설정
- 환경변수와 작업 디렉터리를 설정할 수 있다.
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command("ls", "-l");
// 환경 변수 설정
Map<String, String> env = processBuilder.environment();
env.put("MY_ENV_VAR", "myValue");
// 작업 디렉토리 설정
processBuilder.directory(new File("/path/to/dir"));
try {
processBuilder.start();
} catch (IOException e) {
e.printStackTrace();
}
c. 프로세스의 표준 입력/출력/오류 처리
표준 출력 / 오류 예제
- process 표준 출력(process.getInputStream())과 오류(process.getErrorStream())를 읽어서 처리할 수 있다.
String command = "ping -c 4 www.google.com"
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command("ping", "-c", "4", "www.google.com");
try {
Process process = processBuilder.start();
// 프로세스의 출력 스트림을 읽음
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
// 프로세스의 오류 스트림을 읽음
BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
while ((line = errorReader.readLine()) != null) {
System.err.println(line);
}
// 종료 코드 확인
int exitCode = process.waitFor();
System.out.println("Exit Code: " + exitCode);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
표준 입력 예제
- process에 표준입력(process.getInputStream())이 가능하다.
// ProcessBuilder를 사용하여 cat 명령어 실행
ProcessBuilder processBuilder = new ProcessBuilder("cat");
try {
// 프로세스 시작
Process process = processBuilder.start();
// 표준 입력에 데이터를 쓰는 예시
OutputStream outputStream = process.getOutputStream();
PrintWriter writer = new PrintWriter(outputStream);
// 표준 입력에 데이터 쓰기
writer.println("Hello, ProcessBuilder!"); // 입력할 내용
writer.println("This is a test."); // 추가적인 입력 내용
writer.flush(); // 입력이 완료된 후 flush 호출
writer.close(); // 스트림을 닫아 프로세스에 입력 종료를 알림
// 프로세스의 출력 스트림을 읽음
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
System.out.println("Output from process:");
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
// 종료 코드 확인
int exitCode = process.waitFor();
System.out.println("Exit Code: " + exitCode);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
d.비동기적인 프로세스 실행 및 종료 대기
비동기 실행
- process가 시작될 때 prcess가 종료될 때 까지 기다리지 않는다. 즉 비동기적으로 실행된다.
Process process = processBuilder.start(); // 비동기 실행
종료 대기
- waitFor()은 process가 종료될 때까지 되기하는 메서드이다.
- 프로세스 종료코드를 반환하다.
int exitCode = process.waitFor(); // 프로세스가 종료될 때까지 대기
System.out.println("프로세스 종료 코드: " + exitCode);
'Programming > Java' 카테고리의 다른 글
[JPA] Entity 매핑과 DDL 자동 생성 옵션 정리 (0) | 2024.12.12 |
---|---|
[JPA] JPA 영속성 컨텍스트와 Entity 상태(비영속, 영속, 준영속, 삭제) (1) | 2024.12.06 |
[Java] 클래스 생성과 인스턴스 생성 (1) | 2024.01.05 |
[Java] 스트림(Stream) (0) | 2023.12.10 |
[Java] 쓰레드(Thread) - 6(쓰레드 동기화) (0) | 2023.12.10 |