2016-06-01 2 views
0

저는 현재 리눅스 쉘에서 de/encoding base64 용 Java 파일을 작성하려고합니다. 지금까지 가지고있는 방법은 다음과 같습니다.Java 잡기 터미널 출력

public static String cmdExec(String Base64String) throws java.io.IOException, java.lang.InterruptedException{ 
    String line; 

    try { 
     Process p = Runtime.getRuntime().exec("openssl enc -base64 -d <<< " + Base64String); 
     BufferedReader input = new BufferedReader 
      (new InputStreamReader(p.getInputStream())); 
      while ((line = input.readLine()) != null) { 
      output += (line); 
     } 
     input.close(); 
     } 
    catch (Exception ex) { 
     ex.printStackTrace(); 
    } 
    System.out.println(output); 
    return output; 
} 

유감스럽게도 쉘에 수동으로 입력하면 명령이 작동하지만 출력되지 않습니다.
자바 8 이후의 자바 인코더와 아파치 솔루션을 알고 있지만 커맨드 라인을 통해 실제로 작동시키고 싶습니다.

내가 잘못하고있는 것이 있습니까?

+1

오류를 찾으셨습니까? 'exec' 명령이 맞습니까? 터미널에서 같은 명령을 실행할 때 작동합니까? 실행 파일의 절대 경로없이 작동하는지 확신합니까? '<<<'는'bash'와 같은 통역사 없이는 어떻게 작동합니까? 왜 명령을 여러 개의 문자열 리터럴로 나눠서 읽을 수 없습니까? – Thilo

+1

Thilo의 모든 "whys"플러스 왜'openssl' 대신에'base64' 리눅스 명령을 사용하지 않으시겠습니까? '<<<'를 사용하여 입력을 리디렉션하려고합니까? 그렇다면'-in' 옵션을'openssl enc'에 사용할 수 있습니다. – mhawke

+0

답변 해 주셔서 감사합니다! 나는 어떤 오류도 없으며 exec 명령이 나를 위해 작동하는 것 같다. 또한 쉘에 명령을 입력하면 작동합니다. 나는 예를 들어 openssl 명령을 대안으로 찾았습니다. echo QWxhZGRpbjpvcGVuIHNlc2FtZQ == | base64 - 왜냐하면 내가 echo를 사용한다면, 출력은 QWxhZGRpbjpvcGVuIHNlc2FtZQ ==입니다. base64 --decode (비록 쉘에 직접 입력하면이 기능이 작동합니다.) 명령을 나누는 것이 옳다. 죄송합니다 ... – tobisetsfire

답변

1

. 따라서 openssl<<<이 잘못된 옵션이라고 불평합니다. 너는 stdout을 위해하는 것과 같은 방법으로 p.getErrorStream()을 통해 아이의 표준 오류를 캡처하고 인쇄함으로써 이것을 볼 수 있습니다. 또한 자식 프로세스의 종료 값은 p.exitValue()과 함께 사용할 수 있습니다. 또한 확인해야합니다.

이제 Base64String 인수는 디코딩하려는 base64 인코딩 된 텍스트이므로 해당 텍스트를 하위 입력으로 보낼 필요가 있습니다. 당신은 p.getOuputStream()와 아이의 표준 입력을받을 다음 스트림에 쓸 수 있습니다 : 당신이 아이의 표준 입력을 닫으면

Process p = Runtime.getRuntime().exec("openssl enc -base64 -d"); 
// Process p = Runtime.getRuntime().exec("base64 -d"); // the base64 command also works 
BufferedWriter toChild = new BufferedWriter(
          new OutputStreamWriter(p.getOutputStream())); 
toChild.write(Base64String + "\n"); 
toChild.close(); 

당신은 당신이 현재처럼 p.getInputStream()를 사용하여 디코딩 출력을 읽을 수 있습니다. 위에서 언급했듯이, 자식의 종료 값 (0이 아닌 값은 자식에서 오류가 발생했음을 의미)을 확인하고 종료 값이 0이 아닌 경우 표시 될 수 있도록 자식의 stderr를 수집해야합니다.

마지막으로 하나의 명령 인 base64 -d도 작동하지만 대개 코어 리눅스 유틸리티로 제공되며 openssl을 설치할 필요가 없습니다.

+0

답변 해 주셔서 감사합니다! cmdLine은 "QWxhZGRpbjpvcGVuIHNlc2FtZQ =="와 같은 String입니다.이 예제는 "Aladdin : open sesame"으로 디코드하고 싶습니다. 언급 한 단계를 시도했지만 System.out.println (출력); 예상되는 구 대신에 아무것도 인쇄하지 않습니다 (줄 바꿈). – tobisetsfire

+1

글쎄'<<<'는 쉘에서만 작동하지만'exec()'는 쉘을 사용하여 명령을 실행하지 않으므로 리디렉션이 작동하지 않습니다. 인코딩 된 문자열을 자식의 표준 입력에 써야합니다.이를 위해'p.getOutputStream() '을 사용하십시오. 이 방법을 보여주기 위해 내 대답을 업데이트했습니다. – mhawke

+0

이 모든 단계를 거쳐 Base64 인코딩과 같은 단순한 용도로 순수 Java 솔루션을 사용하는 것이 왜 더 좋은지를 알 수 있기를 바랍니다. – Thilo

-1

어쩌면 Scanner으로 시도 : 아이가 쉘에서 실행되지 않기 때문에 시도 리디렉션 그대로 openssl에 인수로 처리됩니다 그래서이 작동하지 않습니다

String output = ""; 
Process p = Runtime.getRuntime().exec("openssl enc -base64 -d <<< "+cmdLine); 
Scanner s = new Scanner(p.getInputStream()).useDelimiter("\\A"); 
while (s.hasNext()) { 
    output += s.next(); 
} 
s.close();