How to run Linux commands in Java?
Я хочу создать разность двух файлов. Я пытался найти код в Java, который делает это, но не нашел никакого простого кода / служебного кода для этого. Следовательно, я подумал, что если я смогу каким-то образом запустить команду linux diff / sdiff из моего java-кода и заставить ее вернуть файл, в котором хранится diff, это было бы здорово.
Предположим, есть два файла fileA и fileB. Я должен иметь возможность хранить их различия в файле с именем fileDiff через мой код Java. Тогда выборка данных из fileDiff не будет большой проблемой.
11 ответов
Посмотрите на метод Runtime.exec(): http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html
Ты можешь использовать java.lang.Runtime.exec
запустить простой код. Это дает вам обратно Process
и вы можете читать его стандартный вывод напрямую, без необходимости временно сохранять вывод на диске.
Например, вот полная программа, которая покажет, как это сделать:
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class testprog {
public static void main(String args[]) {
String s;
Process p;
try {
p = Runtime.getRuntime().exec("ls -aF");
BufferedReader br = new BufferedReader(
new InputStreamReader(p.getInputStream()));
while ((s = br.readLine()) != null)
System.out.println("line: " + s);
p.waitFor();
System.out.println ("exit: " + p.exitValue());
p.destroy();
} catch (Exception e) {}
}
}
После компиляции и запуска выдает:
line: ./
line: ../
line: .classpath*
line: .project*
line: bin/
line: src/
exit: 0
как и ожидалось.
Вы можете также получить поток ошибок для стандартной ошибки процесса и выходной поток для стандартного ввода процесса, достаточно запутанно. В этом контексте входные и выходные данные меняются местами, поскольку это входные данные от процесса к этому (т. Е. Стандартные выходные данные процесса).
Если вы хотите объединить стандартный вывод процесса и ошибку из Java (в отличие от использования 2>&1
в фактической команде), вы должны посмотреть в ProcessBuilder
,
Вы также можете написать файл сценария оболочки и вызвать этот файл из кода Java. как показано ниже
{
Process proc = Runtime.getRuntime().exec("./your_script.sh");
proc.waitFor();
}
Напишите команды linux в файле сценария, после завершения выполнения вы можете прочитать файл diff на Java.
Преимущество этого подхода в том, что вы можете изменять команды без изменения кода Java.
Вам не нужно хранить разность в третьем файле, а затем читать из. Вместо этого вы используете Runtime.exec
Process p = Runtime.getRuntime().exec("diff fileA fileB");
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
Попробуй использовать unix4j. речь идет о библиотеке в Java для запуска команды Linux. например, если вы получили команду вроде: cat test.txt | grep "вторник" | сед "с / кг / кг / г" | сортировка в этой программе станет: Unix4j.cat("test.txt").grep("вторник"). sed ("s / килограмм / кг / г").sort();
Вы можете вызывать команды времени выполнения из Java как для Windows, так и для Linux.
import java.io.*;
public class Test{
public static void main(String[] args)
{
try
{
Process process = Runtime.getRuntime().exec("pwd"); // for Linux
//Process process = Runtime.getRuntime().exec("cmd /c dir"); //for Windows
process.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line=reader.readLine())!=null)
{
System.out.println(line);
}
}
catch(Exception e)
{
System.out.println(e);
}
finally
{
process.destroy();
}
}
}
Надеюсь, поможет..:)
Runtime run = Runtime.getRuntime();
//The best possible I found is to construct a command which you want to execute
//as a string and use that in exec. If the batch file takes command line arguments
//the command can be constructed a array of strings and pass the array as input to
//the exec method. The command can also be passed externally as input to the method.
Process p = null;
String cmd = "ls";
try {
p = run.exec(cmd);
p.getErrorStream();
p.waitFor();
}
catch (IOException e) {
e.printStackTrace();
System.out.println("ERROR.RUNNING.CMD");
}finally{
p.destroy();
}
Предлагаемые решения могут быть оптимизированы с использованием commons.io, обработки потока ошибок и исключений. Я хотел бы предложить обернуть так для использования в Java 8 или более поздней версии:
public static List<String> execute(final String command) throws ExecutionFailedException, InterruptedException, IOException {
try {
return execute(command, 0, null, false);
} catch (ExecutionTimeoutException e) { return null; } /* Impossible case! */
}
public static List<String> execute(final String command, final long timeout, final TimeUnit timeUnit) throws ExecutionFailedException, ExecutionTimeoutException, InterruptedException, IOException {
return execute(command, 0, null, true);
}
public static List<String> execute(final String command, final long timeout, final TimeUnit timeUnit, boolean destroyOnTimeout) throws ExecutionFailedException, ExecutionTimeoutException, InterruptedException, IOException {
Process process = new ProcessBuilder().command("bash", "-c", command).start();
if(timeUnit != null) {
if(process.waitFor(timeout, timeUnit)) {
if(process.exitValue() == 0) {
return IOUtils.readLines(process.getInputStream(), StandardCharsets.UTF_8);
} else {
throw new ExecutionFailedException("Execution failed: " + command, process.exitValue(), IOUtils.readLines(process.getInputStream(), StandardCharsets.UTF_8));
}
} else {
if(destroyOnTimeout) process.destroy();
throw new ExecutionTimeoutException("Execution timed out: " + command);
}
} else {
if(process.waitFor() == 0) {
return IOUtils.readLines(process.getInputStream(), StandardCharsets.UTF_8);
} else {
throw new ExecutionFailedException("Execution failed: " + command, process.exitValue(), IOUtils.readLines(process.getInputStream(), StandardCharsets.UTF_8));
}
}
}
public static class ExecutionFailedException extends Exception {
private static final long serialVersionUID = 1951044996696304510L;
private final int exitCode;
private final List<String> errorOutput;
public ExecutionFailedException(final String message, final int exitCode, final List<String> errorOutput) {
super(message);
this.exitCode = exitCode;
this.errorOutput = errorOutput;
}
public int getExitCode() {
return this.exitCode;
}
public List<String> getErrorOutput() {
return this.errorOutput;
}
}
public static class ExecutionTimeoutException extends Exception {
private static final long serialVersionUID = 4428595769718054862L;
public ExecutionTimeoutException(final String message) {
super(message);
}
}
Если открытие в окнах
try {
//chm file address
String chmFile = System.getProperty("user.dir") + "/chm/sample.chm";
Desktop.getDesktop().open(new File(chmFile));
} catch (IOException ex) {
Logger.getLogger(Frame.class.getName()).log(Level.SEVERE, null, ex);
{
JOptionPane.showMessageDialog(null, "Terjadi Kesalahan", "Error", JOptionPane.WARNING_MESSAGE);
}
}
Я нашел отличную библиотеку ch.vorburger.exec:
ManagedProcessBuilder pb = new ManagedProcessBuilder("someExec")
.addArgument("arg1")
.setWorkingDirectory(new File("/tmp"))
.getEnvironment().put("ENV_VAR", "...")
.setDestroyOnShutdown(true)
.addStdOut(new BufferedOutputStream(new FileOutputStream(outputFile)))
.setConsoleBufferMaxLines(7000); // used by startAndWaitForConsoleMessageMaxMs
ManagedProcess p = pb.build();
p.start();
p.isAlive();
p.waitForExit();
// OR: p.waitForExitMaxMsOrDestroy(5000);
// OR: p.startAndWaitForConsoleMessageMaxMs("Successfully started", 3000);
p.exitValue();
// OR: p.destroy();
// This works even while it's running, not just when it exited
String output = p.getConsole();
Функция Java для получения результата команды Linux!
public String RunLinuxCommand(String cmd) throws IOException {
String linuxCommandResult = "";
Process p = Runtime.getRuntime().exec(cmd);
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
try {
while ((linuxCommandResult = stdInput.readLine()) != null) {
return linuxCommandResult;
}
while ((linuxCommandResult = stdError.readLine()) != null) {
return "";
}
} catch (Exception e) {
return "";
}
return linuxCommandResult;
}