Java Runtime.exec сбой с пробелом в Linux - PullRequest
0 голосов
/ 04 июля 2018

Я много искал, но не нашел решения. Моя цель - использовать java для вызова команд и получения вывода в windows и linux . Я нашел Runtime.exec метод и провел несколько экспериментов. Все прошло нормально, за исключением случаев, когда в параметрах команды есть место. Тестовый код, как показано ниже, также в github .
Код хорошо работает в Windows, но в Linux выход пуст:

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

public class Main {
public static void main(String[] args) {
    try {
        Runtime rt = Runtime.getRuntime();
        String[] commandArray;
        if (isWindows()) {
            commandArray = new String[]{"cmd", "/c", "dir", "\"C:\\Program Files\""};
        } else {
            commandArray = new String[]{"ls", "\"/root/a directory with space\""};
        }
        String cmd = String.join(" ",commandArray);
        System.out.println(cmd);

        Process process = rt.exec(commandArray);
        BufferedReader input = new BufferedReader(
                new InputStreamReader(process.getInputStream()));
        String result = "";
        String line = null;
        while ((line = input.readLine()) != null) {
            result += line;
        }
        process.waitFor();
        System.out.println(result);

    } catch (Exception e) {
        System.out.println(e.getMessage());
    }
}

public static boolean isWindows() {
    String OS = System.getProperty("os.name").toLowerCase();
    return (OS.indexOf("win") >= 0);
    }
}

если я выполню напечатанную команду непосредственно в bash, то результат будет таким, как ожидалось.

[root@localhost javatest]# javac Main.java 
[root@localhost javatest]# java Main
ls "/root/a directory with space"

[root@localhost javatest]# ls "/root/a directory with space"
a.txt  b.txt
[root@localhost javatest]# 

Может кто-нибудь объяснить, почему и дать способы решить?

1 Ответ

0 голосов
/ 04 июля 2018

Существует две версии exec.

  • exec(String command)

    Здесь вы указываете команду аналогично тому, как вы это делаете в командной строке, т. Е. Вам нужно заключать аргументы в пробелы.

    cmd /c dir "C:\Program Files"
    
  • exec(String[] cmdarray)

    Здесь вы указываете аргументы отдельно, поэтому аргументы задаются как есть, то есть без кавычек. Метод exec позаботится о любых пробелах и кавычках в аргументе, корректно заключая в кавычки и экранируя аргумент, необходимый для выполнения команды.

    cmd
    /c
    dir
    C:\Program Files
    

Итак, удалите добавленные вами дополнительные кавычки:

if (isWindows()) {
    commandArray = new String[] { "cmd", "/c", "dir", "C:\\Program Files"};
} else {
    commandArray = new String[] { "ls", "/root/a directory with space"};
}
...