런타임을 사용하여 Java 프로그램에서 명령 프롬프트 명령을 실행하고 있습니다. 그러나 명령이 반환하는 출력을 얻는 방법을 알지 못합니다.
내 코드는 다음과 같습니다.
Runtime rt = Runtime.getRuntime();
String[] commands = {"system.exe", "-send" , argument};
Process proc = rt.exec(commands);
나는 노력 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);
그러나 출력으로 아무것도 얻지 못하지만 해당 명령을 직접 실행할 때 정상적으로 작동합니다.
답변
갈 길은 다음과 같습니다.
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);
}
자세한 내용은 여기 에서 Javadoc을 읽으 십시오 . ProcessBuilder
사용하는 것이 좋습니다.
답변
더 빠른 방법은 다음과 같습니다.
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() : "";
}
이것은 기본적으로 요약 된 버전입니다.
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;
}
나는이 질문이 오래되었다는 것을 알고 있지만 이것이 더 빠를 것이라고 생각하기 때문에이 답변을 게시하고 있습니다.
답변
ProcessBuilder
제안 된 Senthil을 사용 하는 것 외에도 , Runtime.exec ()가하지 않을 경우 의 모든 권장 사항 을 읽고 구현 해야 합니다 .
답변
classpath에서 이미 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());
답변
또한 명령 출력을 얻기 위해 스트림을 사용할 수 있습니다.
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);
}
답변
@Senthil 및 @Arend 답변 ( https://stackoverflow.com/a/5711150/2268559 )이 언급되었습니다 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);
답변
이 글을 쓰는 시점에서 코드를 포함한 다른 모든 답변은 교착 상태를 초래할 수 있습니다.
프로세스에는 제한된 버퍼 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()
{
}
}
키는 사용하는 것입니다 ProcessBuilder.redirectErrorStream(true)
리디렉션 stderr
에 stdout
스트림입니다. 따라서 stdout
와 사이를 번갈아 가면서 단일 스트림을 읽을 수 있습니다 stderr
. 이를 수동으로 구현 하려면 차단하지 않도록 두 개의 다른 스레드에서 스트림을 사용해야합니다.
