как запустить команды linux в коде java?

<p>я хочу создать разность двух файлов. я пытался найти код в java, который делает это, но не нашел никакого простого кода/служебного кода для этого. поэтому я подумал, что если я смогу каким-то образом запустить команду linux diff/sdiff из моего java-кода и заставить ее вернуть файл, в котором хранится diff, то это было бы здорово.</p><p>предположим, есть два файла filea и fileb. я должен иметь возможность хранить их diff в файле с именем filediff через мой код java. тогда выборка данных из filediff не будет большой проблемой.</p>

<p>ознакомьтесь с методом runtime.exec (): <a href="http://docs.oracle.com/javase/7/docs/api/java/lang/runtime.html#exec(java.lang.string)">http://docs.oracle.com/javase/7/docs/api/java/lang/runtime.html#exec(java.lang.string )</a> </p>

<p>вы можете использовать <a href="http://download-llnw.oracle.com/javase/6/docs/api/java/lang/runtime.html#exec%28java.lang.string%29"><code>java.lang.runtime.exec</code></a> для запуска простого кода. это возвращает вам <code>process</code>, и вы можете читать его стандартный вывод напрямую, без необходимости временно сохранять вывод на диске.</p><p>например, вот полная программа, которая покажет, как это сделать:</p><pre><code>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) {} } } </code></pre><p>после компиляции и запуска выдает:</p><pre><code>line: ./ line: ../ line: .classpath* line: .project* line: bin/ line: src/ exit: 0 </code></pre><p>как и ожидалось.</p><p>вы также можете получить <a href="http://download-llnw.oracle.com/javase/6/docs/api/java/lang/process.html#geterrorstream%28%29">error error</a> для стандартной ошибки процесса и <a href="http://download-llnw.oracle.com/javase/6/docs/api/java/lang/process.html#getoutputstream%28%29">output output</a> для стандартного ввода процесса, достаточно запутанно. в этом контексте ввод и вывод меняются местами, поскольку он вводится <em>из</em> процесса в этот процесс (т. е. стандартный <em>output</em> процесса).</p><p>если вы хотите объединить стандартный вывод процесса и ошибку из java (в отличие от использования <code>2>&1</code> в фактической команде), вы должны изучить <a href="http://download-llnw.oracle.com/javase/6/docs/api/java/lang/processbuilder.html"><code>processbuilder</code></a> .</p>

<p>вы также можете написать файл сценария shell и вызвать этот файл из кода java. как показано ниже</p><pre><code>{ process proc = runtime.getruntime().exec("./your\_script.sh"); proc.waitfor(); } </code></pre><p>напишите команды linux в файле сценария, после завершения выполнения вы можете прочитать файл diff в java.</p><p>преимущество этого подхода в том, что вы можете изменять команды без изменения кода java.</p>

<p>вам не нужно хранить diff в 3-м файле, а затем читать из. вместо этого вы используете <code>runtime.exec</code></p><pre><code>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); } </code></pre>

<p>попробуйте использовать <a href="https://code.google.com/p/unix4j/">unix4j</a> . речь идет о библиотеке на java для запуска команды linux. например, если вы получили команду вроде: cat test.txt | grep "вторник" | сед "с/кг/кг/г" | sort в этой программе станет: unix4j.cat ("test.txt"). grep ("вторник"). sed ("s/килограмм/кг/г"). sort ();</p>

<pre><code>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(); } </code></pre>

<p>вы можете вызывать команды времени выполнения из java как для <strong>windows</strong>, так и для <strong>linux</strong>.</p><pre><code>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(); } } } </code></pre><p>надеюсь, поможет.. :)</p>

<p>предлагаемые решения могут быть оптимизированы с помощью commons.io, обработки потока ошибок и использования исключений. я хотел бы предложить обернуть так для использования в java 8 или более поздней версии:</p><pre><code>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); } } </code></pre>

<p>если открытие в окнах</p><pre><code>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); } } </code></pre>

<p>функция java для получения результата команды linux!</p><pre><code>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; } </code></pre>