2009-12-30 11 views
1

현재 ProcessBuilder를 사용하여 Java 서버에서 명령을 실행 중입니다. 이 서버는 오래된 Perl 서버를 대체하기위한 것이고 많은 레거시 코드는 플랫폼 특정 명령 행을 지정합니다.Java에서 untokenized 명령 행 실행

command -option "hello world" 

및 유닉스에 그것을 할 수 있습니다 : 예를 들어

를, 그것을 할 수있는 창에

command -option 'hello world' 

문제는 ProcessBuilder를하고 Runtime.exec의 모두가 (토큰 화 된 명령 줄에 걸릴 것입니다 유닉스와 윈도우 모두에 대해 { "command", "-option", "hello world"}).

나는 플랫폼 독립적 인 방법을 선호하지만 우리는 코드베이스에서 3 천만 라인의 perl 코드 범위를 가지고 있습니다. 나는 다른 플랫폼을위한 토크 나이저를 쓰지 않고 (큰 문제가 아니라, 단지 WTF를 만들고 싶지 않다.), 운영 체제의 쉘이 명령 행을 토큰 화하도록하는 방법이 있는가?

+0

'명령 - 옵션에 "Hello World"'유닉스에 작품뿐만 아니라 따옴표는 따옴표입니다 ... – akuhn

+0

우리의 코드는 Windows와 Unix에서 조건부로 처리합니다. 대개 명령이 그보다 복잡하고 중첩 된 따옴표와 명령 행 변수 및 기타 그런 말도 안되기 때문입니다. – tster

+0

3 천만 줄의 perl?!? 나는 당신이 아니므로 매우 기쁩니다;) – Fantius

답변

7

단일 문자열을 사용하고 전체 명령으로 실행하는 오버로드 된 Runtime.exec(String)을 사용할 수 있습니까? Windows에서 나를 위해


다음 작품 :

public static void main(String [] args) throws Exception { 
    Process p = new ProcessBuilder(getCommand("perl -e \"print 5\"")).start(); 
    System.out.println(IOUtils.toString(p.getInputStream())); 
    p.destroy(); 

} 

private static String[] getCommand(String input) { 
    StringTokenizer tokenizer = new StringTokenizer(input); 
    String[] result = new String[tokenizer.countTokens()]; 
    for (int i = 0; tokenizer.hasMoreTokens(); i++) { 
     result[i] = tokenizer.nextToken(); 
    } 
    return result; 
} 
+0

프로세스가 실행되고있는 환경의 경로에 Perl이 있습니까? – Kevin

+0

죄송합니다. 방금 Runtime.exec()가 아니라 ProcessBuilder를 사용하고 있다는 것을 알았습니다. – tster

+0

Stderr을 stdout으로 리다이렉트하는 기능을 잃지 않고 Runtime.exec()를 사용하고 있습니까? – tster

5

나는 생각 :

Process p = Runtime.getRuntime().exec("perl -e \"print 5\""); 
System.out.println(IOUtils.toString(p.getInputStream())); 
p.destroy(); 

이 더 많거나 적은 Runtime.exec의 (String)를하고있는 것입니다 따옴표는 쉘에 의해 해석됩니다. 대신, 쉘 스크립트에 명령을 넣어 :

$ cat temp.sh 
#!/bin/sh 
perl -e "print 5" 

하고 실행 :

import java.io.BufferedReader; 
import java.io.InputStreamReader; 

public class PBTest { 

    public static void main(String[] args) { 
     ProcessBuilder pb = new ProcessBuilder("./temp.sh"); 
     pb.redirectErrorStream(true); 
     try { 
      Process p = pb.start(); 
      String s; 
      BufferedReader stdout = new BufferedReader (
       new InputStreamReader(p.getInputStream())); 
      while ((s = stdout.readLine()) != null) { 
       System.out.println(s); 
      } 
      System.out.println("Exit value: " + p.waitFor()); 
      p.getInputStream().close(); 
      p.getOutputStream().close(); 
      p.getErrorStream().close(); 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 
} 

콘솔 :

5 
Exit value: 0