java ProcessBuilder运行shell脚本挂起
我正在尝试使用ProcessBuilder运行shell脚本。该脚本可以工作,但无法在java代码之后运行。错误流不输出消息。我在centOS 6.9计算机上运行它。请在下面找到我的代码java ProcessBuilder运行shell脚本挂起,java,Java,我正在尝试使用ProcessBuilder运行shell脚本。该脚本可以工作,但无法在java代码之后运行。错误流不输出消息。我在centOS 6.9计算机上运行它。请在下面找到我的代码 public static ArrayList<String> runCommand(ArrayList<String> command)throws IOException { ProcessBuilder processBuilder = new ProcessBu
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;
}
公共静态ArrayList运行命令(ArrayList命令)引发IOException{
ProcessBuilder ProcessBuilder=新的ProcessBuilder();
processBuilder.command(command);
Process=processBuilder.start();
BufferedReader=新的BufferedReader(新的InputStreamReader(process.getInputStream());
BufferedReader errorReader=新的BufferedReader(新的InputStreamReader(process.getErrorStream());
ArrayList commandOutput=新的ArrayList();
字符串str;
而((str=reader.readLine())!=null){
commandOutput.add(str);
}
StringBuilder errorBuilder=新建StringBuilder();
而((str=errorReader.readLine())!=null){
errorBuilder.append(str);
}
字符串errorMessage=errorBuilder.toString();
如果(!errorMessage.equals(“”){
String message=LOG_TAG+”,[runCommand]错误:“+errorMessage;
System.out.println(消息);
}
reader.close();
errorReader.close();
process.destroy();
返回命令输出;
}
在您的情况下,您正在从流程的输出流中读取某些内容,直到您消耗掉所有内容。然后,尝试读取错误流
如果进程在错误流中写入了相当数量的字符,那么另一个进程将阻塞,直到它们被使用为止。要同时使用错误流和输出流,需要使用线程
您可以遵循StreamGobbler
技术。您可以从该页面获得一些详细信息:
这是一些受页面影响的代码:
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();
尝试在线程中使用输出流(或通过stdout重定向错误并使用单个线程),并在
进程上使用waitFor
等待它完成执行