Я пытаюсь запустить сценарий оболочки с помощью ProcessBuilder. Скрипт работает, но не может работать после кода Java. И поток ошибок не выводит сообщение. Я запускаю его на компьютере с CentOS 6.9. Пожалуйста, найдите мой код ниже.
public static ArrayList<String> runCommand(ArrayList<String> command)throws IOException {
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command(command);
Process process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
ArrayList<String> commandOutput = new ArrayList<>();
String str;
while((str = reader.readLine()) != null) {
commandOutput.add(str);
}
StringBuilder errorBuilder = new StringBuilder();
while((str = errorReader.readLine()) != null) {
errorBuilder.append(str);
}
String errorMessage = errorBuilder.toString();
if (!errorMessage.equals("")) {
String message = LOG_TAG + ",[runCommand] error:" + errorMessage;
System.out.println(message);
}
reader.close();
errorReader.close();
process.destroy();
return commandOutput;
}




В вашем случае вы читаете что-то из выходного потока процесса, пока не потребляете все. Затем вы пытаетесь прочитать поток ошибок.
Если процесс записывает значительное количество символов в поток ошибок, другой процесс блокируется до тех пор, пока они не будут использованы. Чтобы одновременно использовать поток ошибок и поток вывода, необходимо использовать потоки.
Вы можете следовать методике StreamGobbler. Вы можете получить некоторые подробности на этой странице: https://www.javaworld.com/article/2071275/when-runtime-exec---won-t.html?page=2
Это код, на который повлияла страница:
public class StreamGobbler extends Thread {
private static final String EOL = System.lineSeparator();
private final InputStream inputStream;
private final StringBuilder output = new StringBuilder();
public StreamGobbler(InputStream inputStream) {
this.inputStream = inputStream;
}
public void run() {
try (InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader reader = new BufferedReader(inputStreamReader);
) {
String line;
while ((line = reader.readLine()) != null) {
output.append(line);
output.append(EOL);
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
public String getOutput() {
return output.toString();
}
}
В вашем коде вы используете StreamGobbler следующим образом:
StreamGobbler outputGobbler = new StreamGobbler(process.getInputStream());
StreamGobbler errorGobbler = new StreamGobbler(process.getErrorStream());
process.waitFor();
String commandOutput = outputGobbler.getOutput();
String errorMessage = errorGobbler.getOutput();
process.destroy();
Попробуйте использовать выходные потоки в потоках (или перенаправить ошибку через стандартный вывод и использовать один поток) и используйте
waitForнаprocess, чтобы дождаться завершения выполнения.