Java Runtime.getRuntime () : 명령 행 프로그램 실행에서 출력 얻기
런타임을 사용하여 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 ()가하지 않을 경우 의 모든 권장 사항 을 읽고 구현 해야 합니다 .
@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);
또한 명령 출력을 얻기 위해 스트림을 사용할 수 있습니다.
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);
}
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());
이 글을 쓰는 시점에서 코드를 포함한 다른 모든 답변은 교착 상태를 초래할 수 있습니다.
Processes have a limited buffer for stdout
and stderr
output. If you don't listen to them concurrently, one of them will fill up while you are trying reading the other. For example, you could be waiting to read from stdout
while the process is waiting to write to stderr
. You cannot read from the stdout
buffer because it is empty and the process cannot write to the stderr
buffer because it is full. You are each waiting on each other forever.
Here is a possible way to read the output of a process without a risk of deadlocks:
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()
{
}
}
The key is to use ProcessBuilder.redirectErrorStream(true)
which will redirect stderr
into the stdout
stream. This allows you to read a single stream without having to alternate between stdout
and stderr
. If you want to implement this manually, you will have to consume the streams in two different threads to make sure you never block.
Adapted from the previous answer:
public static String execCmdSync(String cmd, CmdExecResult callback) throws java.io.IOException, InterruptedException {
RLog.i(TAG, "Running command:", cmd);
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(cmd);
//String[] commands = {"system.exe", "-get t"};
BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
StringBuffer stdOut = new StringBuffer();
StringBuffer errOut = new StringBuffer();
// 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);
stdOut.append(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);
errOut.append(s);
}
if (callback == null) {
return stdInput.toString();
}
int exitVal = proc.waitFor();
callback.onComplete(exitVal == 0, exitVal, errOut.toString(), stdOut.toString(), cmd);
return stdInput.toString();
}
public interface CmdExecResult{
void onComplete(boolean success, int exitVal, String error, String output, String originalCmd);
}
Try reading the InputStream
of the runtime:
Runtime rt = Runtime.getRuntime();
String[] commands = {"system.exe", "-send", argument};
Process proc = rt.exec(commands);
BufferedReader br = new BufferedReader(
new InputStreamReader(proc.getInputStream()));
String line;
while ((line = br.readLine()) != null)
System.out.println(line);
You might also need to read the error stream (proc.getErrorStream()
) if the process is printing error output. You can redirect the error stream to the input stream if you use ProcessBuilder
.
'programing tip' 카테고리의 다른 글
자바 스크립트에서 변수 유형 찾기 (0) | 2020.07.04 |
---|---|
schema.rb를 잃어 버렸습니다! (0) | 2020.07.04 |
안드로이드 SDK 위치 (0) | 2020.07.04 |
단위 테스트를 작성할 때 무엇을 테스트해야하는지 어떻게 알 수 있습니까? (0) | 2020.07.04 |
쉘 스크립트에서 디렉토리의 파일 목록을 얻는 방법은 무엇입니까? (0) | 2020.07.04 |