2010-11-18 3 views
0

대화 형 모드에서 서브 프로세스로 sh을 실행하는 Java 프로그램이 있습니다. 입력은 System.in에서 복사되고 출력은 System.out으로 복사됩니다. 예를 들어, 출력이 잘못된 순서로 나타납니다이 대화 형 쉘에서 명령과 같은 pwd을 실행할 때 모든 것을 제외하고 잘 작동 :하위 프로세스의 출력이 잘못된 순서로 나타나는 이유는 무엇입니까?

$ pwd 
$ /home/viz/workspace 

대신

$ pwd 
/home/viz/workspace 
$ 

의 차이입니다 그 첫 번째 경우에 pwd의 출력 전에 프롬프트 $이 인쇄됩니다.

왜 그런 일이 일어나고 어떻게 해결할 수 있습니까? 여기

코드입니다 :

import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 

class StreamCopier implements Runnable { 
    private InputStream in; 
    private OutputStream out; 

    public StreamCopier(InputStream in, OutputStream out) { 
     this.in = in; 
     this.out = out; 
    } 

    public void run() { 
     try { 
      int n; 
      byte[] buffer = new byte[4096]; 
      while ((n = in.read(buffer)) != -1) { 
       out.write(buffer, 0, n); 
       out.flush(); 
      } 
      out.close(); 
     } 
     catch (IOException e) { 
      System.out.println(e); 
     } 
    } 
} 

public class Test { 
    public static void main(String[] args) 
      throws IOException, InterruptedException { 
     Process process = Runtime.getRuntime().exec("sh -i +m"); 
     Thread outThread = new Thread(new StreamCopier(
       process.getInputStream(), System.out)); 
     outThread.start(); 
     Thread errThread = new Thread(new StreamCopier(
       process.getErrorStream(), System.err)); 
     errThread.start(); 
     Thread inThread = new Thread(new StreamCopier(
       System.in, process.getOutputStream())); 
     inThread.start(); 
     process.waitFor(); 
     outThread.join(); 
     errThread.join(); 
     inThread.join(); 
    } 
} 
+0

가 다른 쉘을 어떻게 실행하면 어떻게됩니까을? – dacwe

+0

@dacwe : 지금까지'sh' 작업 만 할 수있었습니다. 시도 'bash는'하지만 IO를하려고하면 중지됩니다. 아마도 다른 옵션이 필요할 것입니다 ('+ m'은 도움이되지 않습니다). – vitaut

답변

1

표준 오류 및 표준 출력 비동기 읽기 데이터를 인쇄 다른 스레드로 이동하기 때문에. 2>&1을 리디렉션하면 작동하지만 Runtime.exec ("파일을 찾을 수 없음 - 2> & 1"이 될 수 있음)으로 작동하는지 확신 할 수 없습니다. 그래서 당신은 sh를 호출하고 출력을 리디렉션 쉘 스크립트를 만들고, Runtime.exec을 사용하여 해당 스크립트를 호출 할 수 있습니다

#!/bin/sh 
sh -i +m 2>&1 

Runtime.exec("customsh"); 
+0

그러나'$'와'/ home/viz/workspace'를 모두 표준 출력으로 출력해야합니까? (그래서 아무런 경쟁자도 없다.) – dacwe

+0

@dacwe No. 명령 줄'sh 1> temp.log'에서''pwd ''를 입력해라. 명령 줄 프롬프트가 표시되지만 pwd 출력은 표시되지 않고 'temp.log'로 이동합니다. – khachik

+0

니스! 다음 vitaut 솔루션입니다! – dacwe

관련 문제