我正在使用运行时从我的Java程序运行命令提示符命令.但是我不知道如何获得命令返回的输出.
这是我的代码:
Runtime rt = Runtime.getRuntime();
String[] commands = {"system.exe", "-send" , argument};
Process proc = rt.exec(commands);
Run Code Online (Sandbox Code Playgroud)
我尝试过,System.out.println(proc);但没有返回任何东西.该命令的执行应返回由分号分隔的两个数字,我怎样才能在变量中打印出来?
这是我现在使用的代码:
String[] commands = {"system.exe", "-get t"};
Process proc = rt.exec(commands);
InputStream stdIn = proc.getInputStream();
InputStreamReader isr = new InputStreamReader(stdIn);
BufferedReader br = new BufferedReader(isr);
String line = null;
System.out.println("<OUTPUT>");
while ((line = br.readLine()) != null)
System.out.println(line);
System.out.println("</OUTPUT>");
int exitVal = proc.waitFor();
System.out.println("Process exitValue: " + exitVal);
Run Code Online (Sandbox Code Playgroud)
但我没有得到任何东西作为我的输出,但当我自己运行该命令它工作正常.
Sen*_*hil 217
这是要走的路:
Runtime rt = Runtime.getRuntime();
String[] commands = {"system.exe", "-get t"};
Process proc = rt.exec(commands);
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(proc.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(proc.getErrorStream()));
// Read the output from the command
System.out.println("Here is the standard output of the command:\n");
String s = null;
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
// Read any errors from the attempted command
System.out.println("Here is the standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
Run Code Online (Sandbox Code Playgroud)
更好地阅读更多细节的Javadoc 在这里.ProcessBuilder是一个很好的选择
735*_*sla 61
更快的方法是:
public static String execCmd(String cmd) throws java.io.IOException {
java.util.Scanner s = new java.util.Scanner(Runtime.getRuntime().exec(cmd).getInputStream()).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
Run Code Online (Sandbox Code Playgroud)
这基本上是这个的浓缩版本:
public static String execCmd(String cmd) throws java.io.IOException {
Process proc = Runtime.getRuntime().exec(cmd);
java.io.InputStream is = proc.getInputStream();
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
String val = "";
if (s.hasNext()) {
val = s.next();
}
else {
val = "";
}
return val;
}
Run Code Online (Sandbox Code Playgroud)
我知道这个问题已经过时但是我发布了这个答案,因为我觉得这可能会更快.
Gil*_*ili 11
在撰写本文时,所有其他包含代码的答案都可能导致死锁。
进程有一个有限的缓冲区stdout和stderr输出。如果您不同时听它们,当您尝试阅读另一个时,其中一个会填满。例如,您可能正在等待读取stdout而进程正在等待写入stderr. 您无法读取stdout缓冲区,因为它是空的,并且进程无法写入stderr缓冲区,因为它已满。你们每个人都在永远地等待对方。
这是一种在没有死锁风险的情况下读取进程输出的可能方法:
public final class Processes
{
private static final String NEWLINE = System.getProperty("line.separator");
/**
* @param command the command to run
* @return the output of the command
* @throws IOException if an I/O error occurs
*/
public static String run(String... command) throws IOException
{
ProcessBuilder pb = new ProcessBuilder(command).redirectErrorStream(true);
Process process = pb.start();
StringBuilder result = new StringBuilder(80);
try (BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream())))
{
while (true)
{
String line = in.readLine();
if (line == null)
break;
result.append(line).append(NEWLINE);
}
}
return result.toString();
}
/**
* Prevent construction.
*/
private Processes()
{
}
}
Run Code Online (Sandbox Code Playgroud)
关键是使用ProcessBuilder.redirectErrorStream(true)which 将重定向stderr到stdout流中。这允许您读取单个流而无需在stdout和之间交替stderr。如果您想手动实现这一点,您将不得不在两个不同的线程中使用流以确保您永远不会阻塞。
@Senthil和@Arend回答(/sf/answers/399780531/)提到了ProcessBuilder.以下是使用ProcessBuilder为命令指定环境变量和工作文件夹的示例:
ProcessBuilder pb = new ProcessBuilder("ls", "-a", "-l");
Map<String, String> env = pb.environment();
// If you want clean environment, call env.clear() first
//env.clear();
env.put("VAR1", "myValue");
env.remove("OTHERVAR");
env.put("VAR2", env.get("VAR1") + "suffix");
File workingFolder = new File("/home/user");
pb.directory(workingFolder);
Process proc = pb.start();
BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
// Read the output from the command:
System.out.println("Here is the standard output of the command:\n");
String s = null;
while ((s = stdInput.readLine()) != null)
System.out.println(s);
// Read any errors from the attempted command:
System.out.println("Here is the standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null)
System.out.println(s);
Run Code Online (Sandbox Code Playgroud)
如果已经在类路径上使用了Apache commons-io,则可以使用:
Process p = new ProcessBuilder("cat", "/etc/something").start();
String stderr = IOUtils.toString(p.getErrorStream(), Charset.defaultCharset());
String stdout = IOUtils.toString(p.getInputStream(), Charset.defaultCharset());
Run Code Online (Sandbox Code Playgroud)
我们也可以使用流来获取命令输出:
public static void main(String[] args) throws IOException {
Runtime runtime = Runtime.getRuntime();
String[] commands = {"free", "-h"};
Process process = runtime.exec(commands);
BufferedReader lineReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
lineReader.lines().forEach(System.out::println);
BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
errorReader.lines().forEach(System.out::println);
}
Run Code Online (Sandbox Code Playgroud)