Запустить команду оболочки из jar? - PullRequest
0 голосов
/ 07 января 2011

Обычный способ вызова команды оболочки из Java - что-то вроде этого:

Process process = Runtime.getRuntime().exec(command);

и работает нормально. Но теперь я экспортировал свой проект в исполняемый файл jar, и команды оболочки callig больше не работают. Есть ли какие-либо объяснения, решения или обходные пути для этой проблемы?

Финес

-

редактирование:

  • даже прерывания клавиатуры (ctrl + c; ctrl + d) не распознаются.

  • Терминальный ввод не будет работать после убийства Java

-

Наименьшая программа:

import java.io.BufferedWriter;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.IOException;

public class Test {
    public static String fileName = "";

    /** test if you can open a 7z archive file with a given password */
    public static boolean test(String password)
        throws IOException, InterruptedException {
        String command = "7z l "+fileName;

        Process process = Runtime.getRuntime().exec(command);

        OutputStream out = process.getOutputStream();
        OutputStreamWriter w = new OutputStreamWriter(out);
        BufferedWriter writer = new BufferedWriter(w);
        writer.write(password+"\n");
        writer.close();
        w.close();
        out.close();

        if(process.waitFor() == 0) {
            return true;
        }
        else {
            return false;
        }
    }

    public static void main(String[] args) throws IOException, InterruptedException {
        fileName = args[0];
        test(args[1]);
    }
}

Ответы [ 3 ]

2 голосов
/ 07 января 2011

Если вы запустите тестовую программу и используете ps или диспетчер задач, вы заметите, что 7z работает. Ваша проблема в том, что вы не потребляете выходные данные Процесса. Поэтому 7z быстро блокируется при попытке вывести содержимое вашего архива.

Если вы добавите перед process.waitFor() следующие строки, вы получите работающую программу:

    InputStream in = process.getInputStream();
    byte[] buf = new byte[256];
    while (true) {
        int c = in.read(buf);
        if (c == -1)
            break;
        System.out.println(new String(buf));
    }

Однако это будет использовать только стандартный процесс, который вам нужен, чтобы сделать то же самое с process.getErrorStream(). Возможно, вам будет проще использовать ProcessBuilder для запуска вашего процесса, поскольку он позволяет объединять потоки stderr и stdout.

2 голосов
/ 07 января 2011

Вы должны прочитать эту превосходную статью JavaWorld о подводных камнях запуска внешних процессов из Java.

1 голос
/ 07 января 2011

Я думаю, ваша проблема связана с базовым путем, из которого выполняется команда. Есть способ установить его явно при вызове exec.

...