IT

Runtime.exec ()에서 파이프를 작동시키는 방법은 무엇입니까?

lottoking 2020. 8. 20. 19:08
반응형

Runtime.exec ()에서 파이프를 작동시키는 방법은 무엇입니까?


다음 코드를 고려하십시오.

String commandf = "ls /etc | grep release";

try {

    // Execute the command and wait for it to complete
    Process child = Runtime.getRuntime().exec(commandf);
    child.waitFor();

    // Print the first 16 bytes of its output
    InputStream i = child.getInputStream();
    byte[] b = new byte[16];
    i.read(b, 0, b.length); 
    System.out.println(new String(b));

} catch (IOException e) {
    e.printStackTrace();
    System.exit(-1);
}

프로그램의 출력은 다음과 가변합니다.

/etc:
adduser.co

물론 쉘에서 실행하면 예상대로 작동합니다.

poundifdef@parker:~/rabbit_test$ ls /etc | grep release
lsb-release

인터넷은 파이프 동작이 크로스 플랫폼이 아니라는 사실 때문에 Java를 생산하는 Java 공장에서 일하는 똑똑한 사람들은 파이프가 작동 보장 할 수 있다는 사실.

어떻게 할 수 있습니까?

자바보다는 구축 나는하여 내 분석을 모두 수행 않을거야 grep그리고 sed내가 언어를 변경하려는 경우, 나는 완전히 무 이동하지 그 언어, 내 구문 분석 코드를 다시 쓰기에 강제 할 것이기 때문에 .

쉘 명령을 호출 할 때 Java가 파이핑 및 리디렉션을 수행해야합니까?


펼쳐보기를 작성하고 별도의 명령 대신 펼쳐보기를 실행하십시오.

파이프는 셸의 일부 다음과 같이 할 수도 있습니다.

String[] cmd = {
"/bin/sh",
"-c",
"ls /etc | grep release"
};

Process p = Runtime.getRuntime().exec(cmd);


"ps -ef | grep someprocess"점을 제외하고는 Linux라는 문제가 발생했습니다.
"ls"를 사용하면 언어에 독립적 인 (더 느리지 만) Java 대체가 있습니다. 예 :

File f = new File("C:\\");
String[] files = f.listFiles(new File("/home/tihamer"));
for (String file : files) {
    if (file.matches(.*some.*)) { System.out.println(file); }
}

"ps"를 사용하면 Java에 API가없는 것 같기 때문에 조금 더 어렵습니다.

Sigar가 우리를 도울 수 있습니다 들었습니다 : https://support.hyperic.com/display/SIGAR/Home

그러나 가장 간단한 방법은 (Kaj가 지적했듯이) 파이프 명령을 어디에 배열로 실행하는 것입니다. 다음은 전체 코드입니다.

try {
    String line;
    String[] cmd = { "/bin/sh", "-c", "ps -ef | grep export" };
    Process p = Runtime.getRuntime().exec(cmd);
    BufferedReader in =
            new BufferedReader(new InputStreamReader(p.getInputStream()));
    while ((line = in.readLine()) != null) {
        System.out.println(line); 
    }
    in.close();
} catch (Exception ex) {
    ex.printStackTrace();
}

문자열 배열이 파이프와 함께 작동하는 이유에 대해 단일 문자열은 작동하지 않지만 ... 우주의 신비 중 하나입니다 (특히 소스 코드를 읽지 않은 경우). exec에 단일 문자열이 주어지면 먼저 파싱하기 때문이라고 생각합니다 (좋지 않은 방식으로). 반대로 exec에 문자열 배열이 주어지면 구문 분석하지 않고 단순히 운영 체제에 전달합니다.

사실, 바쁜 하루에 시간을내어 소스 코드 ( http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/)를 보면 Runtime.java # Runtime.exec % 28java.lang.String % 2Cjava.lang.String [] % 2Cjava.io.File % 29 ), 정확히 무슨 일이 일어나고 있는지 확인합니다.

public Process  [More ...] exec(String command, String[] envp, File dir) 
          throws IOException {
    if (command.length() == 0)
        throw new IllegalArgumentException("Empty command");
    StringTokenizer st = new StringTokenizer(command);
    String[] cmdarray = new String[st.countTokens()];
    for (int i = 0; st.hasMoreTokens(); i++)
        cmdarray[i] = st.nextToken();
    return exec(cmdarray, envp, dir);
}

각 프로세스를 실행할 런타임을 만듭니다. 첫 번째 런타임에서 OutputStream을 가져 와서 두 번째 런타임에서 InputStream으로 복사합니다.

참고 URL : https://stackoverflow.com/questions/5928225/how-to-make-pipes-work-with-runtime-exec

반응형