1. 개요
ip에 ping을 날려 네트워크 상태를 체크하는 프로세스를 개발해야 했다.
지난 시간에는 파이썬의 fabric이라는 라이브러리를 사용하여 시스템 명령어(ping, ll, mkdir 등)을 사용했었는데, 자바로도 구현을 해보고 싶어서 자바에서 사용하는 명령줄 도구를 찾아보았는데, 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' 카테고리의 다른 글
[Java] 클래스 생성과 인스턴스 생성 (1) | 2024.01.05 |
---|---|
[Java] 스트림(Stream) (0) | 2023.12.10 |
[Java] 쓰레드(Thread) - 6(쓰레드 동기화) (0) | 2023.12.10 |
[Java] 쓰레드(Thread) - 5(쓰레드 상태와 실행제어) (0) | 2023.12.10 |
[Java] 쓰레드(Thread) - 4(데몬 쓰레드) (0) | 2023.12.10 |