2011-01-12 4 views
1

내가 누구의 JavaDoc 내용의 Runtime.getRuntime().exec(...) 방법을 사용하여 예를 들어, 별도의 프로세스에서 명령을 실행 : I 프로세스가 살 것이다 것을 알고,이 과정에서 스트림을 어떻게해야합니까 무엇외부 프로세스에서 불필요한 스트림을 어떻게 처리합니까?

Executes the specified command and arguments in a separate process. 

을 Java 프로그램이 존재할 때까지? (이것은 세부 사항이지만 Java 프로그램은이 프로세스를 중지시키고 프로세스 자체는 더 이상 실행되지 않는 Java 프로그램을 발견하면 프로세스 자체가 안전함을 내장하고 있습니다.)

이 프로세스가 출력을 전혀 생성하지 않는다고 생각하면 (예를 들어 모든 오류 메시지와 표준 출력이/dev/null로 리디렉션되고 모든 통신이 파일/소켓/기타를 사용하여 수행되기 때문에) 무엇을해야합니까? 입력 스트림에?

stdout/stderr을 읽으려고 하나 또는 두 개의 Java 스레드를 실행해야합니까?

stdout/stderr을 전혀 생성하지 않는 Java 프로그램에서 생성 된 긴 수명의 외부 프로세스를 처리하는 올바른 방법은 무엇입니까?

편집 기본적으로 나는 는/dev/ null로 모든 리디렉션 확인합니다 다른 쉘 스크립트에서 쉘 스크립트를 래핑. 내 "outter"쉘 스크립트 (모든 것을/dev/null로 리디렉션하는 경우)가 여전히 stdout 또는 stderr에 생성되는 경우 Un * x가 호환되지 않을 것이라고 확신합니다. 그러나 나는 어쨌든 애플 리케이션의 수명주기 동안 스레드를 "아무것도를 위해"실행하도록되어 있어야한다는 생각이 들었다. 정말 마음을 불허합니다.

답변

1

모든 것이 사실이라면 무시할 수 있습니다.

그러나 드물게 일이 그렇게 깔끔하게 해결됩니다. 경우에 따라 stdout/stderr을 가져 오기 위해 하나의 스레드를 생성하는 것이 장기적으로 가치가있을 수 있습니다. 어느 날 실패하고 실제로 뭔가를 내면, 무엇이 나왔는지 알 필요가있는 날입니다. 1 또는 2 스레드 (나는 그것이 단지 하나만으로 끝날 수 있다고 생각한다.) 큰 오버 헤드가되지는 않을 것이다. 특히 당신이 옳고 그 물줄기에서 나오는 것이 아무것도 없다면.

+0

흥미 롭습니다. 내 질문을 편집합니다 ... 기본적으로 모든 경로를 */dev/null *로 리디렉션하는 다른 쉘 스크립트에서 쉘 스크립트를 래핑합니다. * "outter"쉘 스크립트 (*/dev/null *로 모든 것을 리디렉션하는 스크립트)가 여전히 * stdout * 또는 * stderr *에서 아무 것도 생성하지 않으면 내 Un * x가 호환되지 않을 것이라고 확신합니다. – SyntaxT3rr0r

+0

@ SyntaxT3rr0r - 이해합니다. 나는 편집증 환자 중 한 명 일 뿐이야. :) 나는 여분의 스레드가 아마도 불필요하다는 것에 동의한다. – rfeak

1

프로세스의 입력 및 출력을 처리하는 올바른 방법은 사용자가 관심이 없으면 즉시 닫는 것입니다. 자식 프로세스가 stdin 또는 stdout에서 각각 read 또는 write를 호출하려고 시도하면 IOException이 발생합니다. 읽거나 쓸 수 없다는 사실을 처리하는 것은 자식 프로세스의 책임입니다.

대부분의 프로세스는 쓰지 않고 조용히 버리고 쓸 수 없다는 사실을 무시합니다. 이것은 System.out이 PrintWriter 인 Java에서 true이므로 stdout에 의해 throw 된 IOException은 무시됩니다. 출력을/dev/null로 리다이렉트 할 때 일어나는 일과 거의 흡사하다. 모든 출력은 무시된다.

프로세스에 대한 API를 읽은 것으로 보이고 독자적인 쓰기 또는 읽기를 원할 경우 프로세스를 읽고 쓰는 것이 중요한 이유는 분명합니다. 그러나 나는 반복 할 것이다. 문제는 몇몇 운영체제가 (특히) stdout을 위해 매우 제한된 버퍼만을 할당했기 때문에,이 버퍼를 채우지 않는 것이 중요하다. 이것은 자식 프로세스의 출력을 즉시 읽거나 프로세스의 출력을 요구하지 않고 보유한 모든 리소스를 해제 할 수 있음을 OS에 알리는 것을 의미하며 stdout에 쓰거나 stdin에서 읽으려는 시도를 더 이상 거부합니다 (오히려 리소스가 사용 가능해질 때까지 교수형에 처하는 것보다).

+0

답변을 주셔서 감사합니다 ... 그것은 내가 읽은 것만이 아닙니다. 그것은 그것을 읽었으며 지난 수년간 Java에서 외부 프로세스를 시작할 때 일관되게 b ****에 물 렸습니다. 그래서 지금 나는 상당히 급진적 인 접근을하고 있습니다. 사실 저는 방금 다른 것을 생각했습니다. "outter"스크립트는 "nohup"을 수행하여 hangups/kill에 면역이되는 또 다른 스크립트를 생성하고, 스트림에는 Java와 아무런 관련이 없습니다 **. 따라서 Java에서 내부 스크립트는 Java에서 보이지 않을 것임을 알면서 잠시 후 "outter"스크립트를 읽고 닫을 수 있습니다. – SyntaxT3rr0r

+0

자식 프로세스가 반드시 Java VM이 아니므로 반드시 IOException을 throw 할 수는 없습니다. . 예를 들어'SIGPIPE'를받을 수 있습니다 – finnw

+0

@finnw 요점은 무엇인지 모르겠습니다. JVM은 동일한 SIGPIPE를 받고 IOException이 발생하면 IOException을 발생시킵니다. 어떤 프로세스가 SIGPIPE를 받았을 때 그것이 무엇을 하는가는 그것에 달려있다. 나는 grep과 같은 프로그램이 SIGPIPE를 받으면 종료 하겠지만, firefox 나 vlc는 상관하지 않을 것이라고 생각한다. – Dunes

관련 문제