programing

입력/출력 스트림을 사용하는 Java 프로세스

prostudy 2022. 9. 4. 11:55
반응형

입력/출력 스트림을 사용하는 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/bashcmd.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

반응형