입력/출력 스트림을 사용하는 Java 프로세스
아래 코드 예가 있습니다.배쉬하다 echo test
을 사용하다하만 、 첫첫 、 읽후읽후후 。른른른른?
왜이이 짓을 ?? ??? 니면 제제 가못 못못 못? ???는 /대한 하는 스레드 입니다.이것에 의해, 「/bash」는, 「/bash」는 「/bash」로 설정됩니다.OutputStream
★★★★★★★★★★★★★★★★★」InputStream
작업을 중단하지 않고 함께 작업해야 합니다..java.io.IOException: Broken pipe
은은생 은??
고마워요.
String line;
Scanner scan = new Scanner(System.in);
Process process = Runtime.getRuntime ().exec ("/bin/bash");
OutputStream stdin = process.getOutputStream ();
InputStream stderr = process.getErrorStream ();
InputStream stdout = process.getInputStream ();
BufferedReader reader = new BufferedReader (new InputStreamReader(stdout));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stdin));
String input = scan.nextLine();
input += "\n";
writer.write(input);
writer.flush();
input = scan.nextLine();
input += "\n";
writer.write(input);
writer.flush();
while ((line = reader.readLine ()) != null) {
System.out.println ("Stdout: " + line);
}
input = scan.nextLine();
input += "\n";
writer.write(input);
writer.close();
while ((line = reader.readLine ()) != null) {
System.out.println ("Stdout: " + line);
}
우선 라인 교체를 추천합니다.
Process process = Runtime.getRuntime ().exec ("/bin/bash");
선과 함께
ProcessBuilder builder = new ProcessBuilder("/bin/bash");
builder.redirectErrorStream(true);
Process process = builder.start();
ProcessBuilder Java 5 process process process process 。제 생각에, 가장 중요한 개선점은Runtime.getRuntime().exec()
하위 프로세스의 표준 오류를 표준 출력으로 리디렉션할 수 있습니다.은 1번, 1번, 밖에 없다는 입니다.InputStream
읽을 수 있습니다.두 의 스레드가 따로 , 는 2개의 스레드이고, 는 1개의 스레드입니다.stdout
한 번 .stderr
표준 출력 버퍼가 비어 있을 때 표준 오류 버퍼가 채워지지 않도록 합니다(자녀 프로세스가 중단됨). 또는 그 반대도 마찬가지입니다.
다음으로 (2개의 루프가 있습니다)
while ((line = reader.readLine ()) != null) {
System.out.println ("Stdout: " + line);
}
는 출구가 한다.reader
프로세스의 표준 출력에서 읽어낸 는 파일의 끝을 반환합니다. 것은 '아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아.bash
프로세스가 종료됩니다.현재 프로세스에서 더 이상 출력이 없을 경우 파일 끝은 반환되지 않습니다.대신 프로세스의 다음 출력 행을 기다렸다가 다음 행이 표시될 때까지 돌아오지 않습니다.
이 루프에 도달하기 전에 프로세스로2 행의 입력이 송신되기 때문에, 이 2 행의 입력 후에 프로세스가 종료하지 않으면, 이 2 개의 루프 중 첫 번째가 행해집니다.다른 행이 읽히기를 기다리면서 거기에 놓여있지만, 다른 행이 읽히지는 않을 것입니다.
소스 를 컴파일했습니다에 Windows를 했습니다)./bin/bash
cmd.exe
.) 라는 것을 되었습니다: ), ), ), ), ), ), ), ) ) ) ) ) ) ) ) ) ) ) 이치노
- 두 줄 입력 후 처음 두 명령어의 출력이 나타나지만 프로그램이 중단됩니다.
- 를 들어, " " 라고 하면,
echo test
, , 을 누릅니다.exit
은, 「 」이래의 첫cmd.exe
프로세스가 종료되었습니다.그런 다음 프로그램은 다른 입력 행을 요청하고(무시), 하위 프로세스가 이미 종료되었기 때문에 두 번째 루프를 바로 건너뛴 다음 자동으로 종료합니다. - 내가 입력한다면
exit
그리고 나서.echo test
파이프가 닫혀 있다는 IOException이 표시됩니다.이것은 예상대로입니다.첫 번째 입력 행으로 인해 프로세스가 종료되고 두 번째 행은 전송되지 않습니다.
당신이 원하는 것 같은 것을 하는 트릭을 제가 예전에 작업하던 프로그램에서 본 적이 있습니다.이 프로그램은 다수의 셸을 유지하며 셸에서 명령을 실행하고 이러한 명령어의 출력을 읽습니다.사용된 트릭은 항상 셸 명령어 출력의 끝을 표시하는 '매직' 행을 작성하고, 셸로 전송된 명령어 출력이 언제 종료되었는지 확인하는 것입니다.
당신의 코드를 가져다가 모든 걸 바꿔놨어요writer
다음 루프를 사용합니다.
while (scan.hasNext()) {
String input = scan.nextLine();
if (input.trim().equals("exit")) {
// Putting 'exit' amongst the echo --EOF--s below doesn't work.
writer.write("exit\n");
} else {
writer.write("((" + input + ") && echo --EOF--) || echo --EOF--\n");
}
writer.flush();
line = reader.readLine();
while (line != null && ! line.trim().equals("--EOF--")) {
System.out.println ("Stdout: " + line);
line = reader.readLine();
}
if (line == null) {
break;
}
}
이렇게 하면 몇 가지 명령어를 확실하게 실행할 수 있고 각각의 명령어의 출력을 개별적으로 확인할 수 있습니다.
두 사람echo --EOF--
셸로 전송되는 행에 있는 명령어는 명령어로부터의 출력이 다음과 같이 종료되도록 하기 위해 있습니다.--EOF--
명령에서 오류가 발생한 경우에도 마찬가지입니다.
물론 이 방법에는 한계가 있습니다.이러한 제한은 다음과 같습니다.
- 사용자 입력을 기다리는 명령어(예를 들어 다른 셸)를 입력하면 프로그램이 행업하는 것처럼 보입니다.
- 셸에 의해 실행되는 각 프로세스가 새로운 행으로 출력되는 것을 전제로 하고 있습니다.
- 셸에 의해 실행되고 있는 명령어가 행을 쓸 경우 조금 혼란스러워집니다.
--EOF--
. bash
일치하지 않는 텍스트를 입력하면 구문 오류가 보고되고 종료됩니다.)
.
이러한 포인트는 스케줄링된 태스크로 실행하려는 것이 무엇이든 이러한 병리학적 방법으로 동작하지 않는 명령어 또는 소규모 명령어 세트로 제한될 경우 문제가 되지 않을 수 있습니다.
편집: Linux에서 실행 후 종료 처리 및 기타 사소한 변경 사항을 개선합니다.
입력 읽기에는 데몬 스레드 같은 스레드를 사용할 수 있으며, 메인 스레드에 루프하는 동안 이미 출력 리더가 들어가 읽기 및 쓰기를 동시에 할 수 있습니다.프로그램을 다음과 같이 수정할 수 있습니다.
Thread T=new Thread(new Runnable() {
@Override
public void run() {
while(true)
{
String input = scan.nextLine();
input += "\n";
try {
writer.write(input);
writer.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
} );
T.start();
위와 같이 읽을 수 있습니다.
while ((line = reader.readLine ()) != null) {
System.out.println ("Stdout: " + line);
}
최종 작가로 만들지 않으면 내부 계층에서 접근할 수 없습니다.
당신은 가지고 있다writer.close();
당신의 코드로.따라서 bash는 EOF를 수신합니다.stdin
및 종료합니다.그럼 넌 얻을 수 있어Broken pipe
에서 읽으려고 할 때stdout
사라졌던 배시의.
언급URL : https://stackoverflow.com/questions/3643939/java-process-with-input-output-stream
'programing' 카테고리의 다른 글
목록을 쉼표로 구분하는 가장 간단한 방법? (0) | 2022.09.04 |
---|---|
알파벳 순서로 문자열 비교 (0) | 2022.09.04 |
Java 오류:기본 생성자에 대해 암시적 수퍼 생성자가 정의되지 않았습니다. (0) | 2022.09.04 |
VueJs의 전체 애플리케이션에서 액세스할 수 있는 상수를 만드는 가장 좋은 방법은 무엇입니까? (0) | 2022.09.04 |
삭제되지 않는 Vue 구성 요소 찾기 (0) | 2022.09.03 |