자동화 스크립트의 일환으로 Java에서 외부 쉘 스크립트를 실행하고 그 출력 결과(stdout)를 읽어오려고 합니다.
코드:
import java.io.*;
public class ScriptRunner {
public static void main(String[] args) throws IOException {
Process process = new ProcessBuilder("sh", "-c", "while true; do echo 'logging data...'; sleep 1; done").start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println("Output: " + line);
}
}
}
오류: 프로세스가 처음 몇 줄의 출력만 내보낸 뒤, 더 이상 출력이 나오지 않고 프로그램이 멈춘 것처럼 대기 상태(Hang)가 됩니다.
시도: ProcessBuilder의 redirectErrorStream(true) 설정을 통해 표준 에러와 표준 출력을 합쳐보았으나 동일한 현상이 발생했습니다.
질문: 프로세스의 출력 버퍼가 가득 차서 발생하는 데드락 현상인지, 이를 해결하기 위해 별도의 스레드로 스트림을 소비해야 하는 것이 정석인지 궁금합니다.
댓글6
-
빗방울
2026.10.30 17:50
-
빗방울
2026.10.30 18:41
혹시 스크립트 내부에서 버퍼링 설정 되어있는지 확인해보셈.
stdbuf 같은 걸로 라인 버퍼링 강제하면 풀릴 수도 있을 듯함.
원래 외부 프로세스 연동하는 게 은근히 빡셈ㅋㅋ
-
빗방울
2026.10.30 22:05
오 맞음 stdbuf 진짜 꿀팁이네요ㅋㅋ
리눅스 기본 버퍼링 때문에 밀리는 경우 많아서 저것도 확인해보면 좋을듯함
-
빗방울
2026.10.30 21:53
내 생각엔 프로세스 종료 대기하는 waitFor() 위치나 타임아웃 설정 쪽도 한번 체크해보셈.
자바에서 외부 프로세스 제어하는 게 생각보다 ㅈㄴ 까다롭긴 함ㅋㅋ
-
빗방울
2026.10.30 21:54
이거 혹시 쉘 스크립트 자체에서 출력 양이 너무 많아서 그런 거 아님? 내 생각엔 프로세스 옵션에서 버퍼 사이즈 조절하는 쪽도 한번 봐보셈ㅋㅋ
-
빗방울
2026.10.30 22:09
근본적으로는 Apache Commons Exec 같은 라이브러리 써보시는 거 추천함ㅋㅋ 직접 구현하는 것보다 훨씬 편하고 안정적이라 정신건강에 이득임ㄷㄷ
모든 이야기1454
가벼운 안부부터 깊은 생각까지, 함께 나눠요.
이거 전형적인 버퍼 꽉 차서 뻗는 현상 같네요.
스레드 따로 파서 읽거나 그냥 inheritIO() 써보시는 건 어떠신지.
전 예전에 이걸로 고생 좀 했음ㅋㅋ