Java Interacting with Command Propmt [duplicate] - java

This question already has answers here:
Execute external program through terminal in Java
(4 answers)
Executing another java program from our java program [duplicate]
(3 answers)
Closed 4 years ago.
Using
String cmdString = "cmd.exe /c start python ";
Process p = Runtime.getRuntime().exec(cmdString);
I can open the command prompt and run python. I now want to interact with the command prompt. I have read that using
public static void main(String[] args)
{
BufferedWriter writerToProc;
String scriptPath = "C:\\Users\\MichaelMi\\Documents\\SourceTree\\NODE-Sensor-Configurator\\src\\application\\resources\\BACnet-CMD-Line-Upgrader\\UpgradeApplication.py";
String iniPath = "C:\\Users\\MichaelMi\\Documents\\SourceTree\\NODE-Sensor-Configurator\\src\\application\\resources\\BACnet-CMD-Line-Upgrader\\BACpypes.ini";
String execString = "python " + scriptPath + " --ini " + iniPath;
String cmdString = "cmd.exe /c start " + execString ;
try {
Process p = Runtime.getRuntime().exec(cmdString);
writerToProc = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
writerToProc.write(cmdString);
writerToProc.flush();
writerToProc.write("whois\n");
writerToProc.flush();
readErrors(p);
readOutput(p);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void readOutput(Process p)
{
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
Runnable task = new Runnable() {
#Override
public void run() {
try {
if(stdInput.ready())
{
stdInput.lines().forEach((l) -> System.out.println(l));
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
Thread backgroundThread = new Thread(task);
backgroundThread.setDaemon(true);
backgroundThread.start();
}
public static void readErrors(Process p)
{
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
Runnable task = new Runnable() {
#Override
public void run() {
try {
if(stdError.ready())
{
stdError.lines().forEach((l) -> System.out.println(l));
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
Thread backgroundThread = new Thread(task);
backgroundThread.setDaemon(true);
backgroundThread.start();
}
Is supposed to allow me to write to the open command prompt. However this is not working for me. I am getting no exceptions thrown or status errors. I simply do not know how to write to an open command prompt.

I see two problems in your code:
One problem is the used command-line:
cmd.exe /c start python This starts a new cmd.exe instance which itself the uses start to start a detached python process. The detached process is therefore not connected to your BufferedReader/BufferedWriter.
Your second problem is that python does not execute your "1+1" via stdin.
You can simply verify that by creating a file test with the context 1+1\n and execute it on the console: python < test. You will see no output.
See also piping from stdin to a python code in a bash script.

In this case you need to close the input stream before you can read the output streams of the python process. If anyone knows a better way please let us know.
public static void main(String[] args) {
String cmdString = "python";
try {
ProcessBuilder pb = new ProcessBuilder(cmdString);
Process pr = pb.start();
try (BufferedReader readerOfProc = new BufferedReader(
new InputStreamReader(pr.getInputStream()));
BufferedReader errorsOfProc = new BufferedReader(
new InputStreamReader(pr.getErrorStream()))) {
try (BufferedWriter writerToProc = new BufferedWriter(
new OutputStreamWriter(pr.getOutputStream()));) {
writerToProc.write("myVar=1+1\r\n");
writerToProc.write("print(myVar)\r\n");
writerToProc.flush();
} catch (Exception e) {
e.printStackTrace();
}
String s;
while ((s = readerOfProc.readLine()) != null) {
System.out.println("stdout: " + s);
}
while ((s = errorsOfProc.readLine()) != null) {
System.out.println("stdout: " + s);
}
System.out.println("exit code: " + pr.waitFor());
}
} catch (Exception e) {
e.printStackTrace();
}
}
Hope this helps!

Related

Run a shell file in java

In Java you can call a shell file like this:
public class Shell {
private static Shell rootShell = null;
private final Process proc;
private final OutputStreamWriter writer;
private Shell(String cmd) throws IOException {
this.proc = new ProcessBuilder(cmd).redirectErrorStream(true).start();
this.writer = new OutputStreamWriter(this.proc.getOutputStream(), "UTF-8");
}
public void cmd(String command) {
try {
writer.write(command+'\n');
writer.flush();
} catch (IOException e) { }
}
public void close() {
try {
if (writer != null) {
writer.close();
if(proc != null) {
proc.destroy();
}
}
} catch (IOException ignore) {}
}
public static void exec(String command) {
Shell.get().cmd(command);
}
public static Shell get() {
if (Shell.rootShell == null) {
while (Shell.rootShell == null) {
try {
Shell.rootShell = new Shell("su"); //Open with Root Privileges
} catch (IOException e) { }
}
}
return Shell.rootShell;
}
}
Shell.exec("echo " + bt.getLevel() + " > "+ flashfile);
right.
but I have a shell which giving an argument after executing it.
how can I pass that argument? I don't want user type anything to run this shell file. in another word, I want to fully automate a shell file.
If you want to automate a shell file with a Java programme, this can be done. You could even pipe a series of commands to this programme saved in a file and executing these as a batch.
You can execute commands batches of commands from like this:
java -cp experiments-1.0-SNAPSHOT.jar ConsoleReader < commands.txt
commands.txt is a file with a series of commands:
cmd /k date
cmd /k dir
netstat
ipconfig
Or you can with the same programme allow the user to execute commands on the command line.
Below you can find a sample programme which you can compile and be run in the above described manner.
What does it do?
It hooks a java.util.Scanner to the console input and consumes each line.
Then it spawns two threads which listen to the error and input streams and write out either to stderr or stdin.
Empty lines on the console are ignored
If you type "read " it will execute the commands on that file.
Source:
public class ConsoleReader {
public static void main(String[] args) throws IOException, DatatypeConfigurationException {
try(Scanner scanner = new Scanner(new BufferedInputStream(System.in), "UTF-8")) {
readFromScanner(scanner);
}
}
private static final Pattern FILE_INPUT_PAT = Pattern.compile("read\\s*([^\\s]+)");
private static void readFromScanner(Scanner scanner) {
while (scanner.hasNextLine()) {
try {
String command = scanner.nextLine();
if(command != null && !command.trim().isEmpty()) {
command = command.trim();
if("exit".equals(command)) {
break; // exit shell
}
else if(command.startsWith("read")) { // read from file whilst in the shell.
readFile(command);
}
else {
Process p = Runtime.getRuntime().exec(command);
Thread stdout = readFromStream(p.getInputStream(), System.out, "in");
Thread stderr = readFromStream(p.getErrorStream(), System.err, "err");
stdout.join(200);
stderr.join(200);
}
}
}
catch(Exception e) {
Logger.getLogger("ConsoleReader").log(Level.SEVERE, String.format("Failed to execute command %s", e));
}
}
}
private static void readFile(String command) throws FileNotFoundException {
Matcher m = FILE_INPUT_PAT.matcher(command);
if(m.matches()) {
String file = m.group(1);
File f = new File(file);
if (f.exists()) {
try (Scanner subScanner = new Scanner(f)) {
readFromScanner(subScanner);
}
}
}
else {
System.err.printf("Oops, could not find '%s'%n", command);
}
}
private static Thread readFromStream(InputStream stdin, PrintStream out, String name) throws IOException {
Thread thread = new Thread(() -> {
try (BufferedReader in = new BufferedReader(new InputStreamReader(stdin))) {
String line;
while ((line = in.readLine()) != null) {
out.println(line);
}
} catch (IOException e) {
Logger.getLogger("ConsoleReader").log(Level.SEVERE, "Failed to read from stream.", e);
}
}, name);
thread.setDaemon(true);
thread.start();
return thread;
}
}
Runtime.getRuntime().exec("src/[FILE LOCATION]");
I think this is the command you're looking for. Let me know if it works!

FFMpeg process created from Java on CentOS doesn't exit

I need to convert a lot of wave files simultaneously. About 300 files in parallel. And new files come constantly. I use ffmpeg process call from my Java 1.8 app, which is running on CentOS. I know that I have to read error and input streams for making created process from Java possible to exit.
My code after several expirements:
private void ffmpegconverter(String fileIn, String fileOut){
String[] comand = new String[]{"ffmpeg", "-v", "-8", "-i", fileIn, "-acodec", "pcm_s16le", fileOut};
Process process = null;
BufferedReader reader = null;
try {
ProcessBuilder pb = new ProcessBuilder(comand);
pb.redirectErrorStream(true);
process = pb.start();
//Reading from error and standard output console buffer of process. Or it could halts because of nobody
//reads its buffer
reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String s;
//noinspection StatementWithEmptyBody
while ((s = reader.readLine()) != null) {
log.info(Thread.currentThread().getName() + " with fileIn " + fileIn + " and fileOut " + fileOut + " writes " + s);
//Ignored as we just need to empty the output buffer from process
}
log.info(Thread.currentThread().getName() + " ffmpeg process will be waited for");
if (process.waitFor( 10, TimeUnit.SECONDS )) {
log.info(Thread.currentThread().getName() + " ffmpeg process exited normally");
} else {
log.info(Thread.currentThread().getName() + " ffmpeg process timed out and will be killed");
}
} catch (IOException | InterruptedException e) {
log.error(Thread.currentThread().getName() + "Error during ffmpeg process executing", e);
} finally {
if (process != null) {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
log.error("Error during closing the process streams reader", e);
}
}
try {
process.getOutputStream().close();
} catch (IOException e) {
log.error("Error during closing the process output stream", e);
}
process.destroyForcibly();
log.info(Thread.currentThread().getName() + " ffmpeg process " + process + " must be dead now");
}
}
}
If I run separate test with this code it goes normally. But in my app I have hundreds of RUNNING deamon threads "process reaper" which are waiting for ffmpeg process finish. In my real app ffpmeg is started from timer thread. Also I have another activity in separate threads, but I don't think that this is the problem. Max CPU consume is about 10%.
Here is that I usual see in thread dump:
"process reaper" #454 daemon prio=10 os_prio=0 tid=0x00007f641c007000 nid=0x5247 runnable [0x00007f63ec063000]
java.lang.Thread.State: RUNNABLE
at java.lang.UNIXProcess.waitForProcessExit(Native Method)
at java.lang.UNIXProcess.lambda$initStreams$3(UNIXProcess.java:289)
at java.lang.UNIXProcess$$Lambda$32/2113551491.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
What am I doing wrong?
UPD:
My app accepts a lot of connects with voice traffic. So I have about 300-500 another "good" threads in every moment. Could it be the reason? Deamon threads have low priority. But I don't beleive that they really can't do their jobs in one hour. Ususally it takes some tens of millis.
UPD2:
My synthetic test that runs fine. I tried with new threads option and without it just with straigt calling of run method.
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
public class FFmpegConvert {
public static void main(String[] args) throws Exception {
FFmpegConvert f = new FFmpegConvert();
f.processDir(args[0], args[1], args.length > 2);
}
private void processDir(String dirPath, String dirOutPath, boolean isNewThread) {
File dir = new File(dirPath);
File dirOut = new File(dirOutPath);
if(!dirOut.exists()){
dirOut.mkdir();
}
for (int i = 0; i < 1000; i++) {
for (File f : dir.listFiles()) {
try {
System.out.println(f.getName());
FFmpegRunner fFmpegRunner = new FFmpegRunner(f.getAbsolutePath(), dirOut.getAbsolutePath() + "/" + System.currentTimeMillis() + f.getName());
if (isNewThread) {
new Thread(fFmpegRunner).start();
} else {
fFmpegRunner.run();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
class FFmpegRunner implements Runnable {
private String fileIn;
private String fileOut;
FFmpegRunner(String fileIn, String fileOut) {
this.fileIn = fileIn;
this.fileOut = fileOut;
}
#Override
public void run() {
try {
ffmpegconverter(fileIn, fileOut);
} catch (Exception e) {
e.printStackTrace();
}
}
private void ffmpegconverter(String fileIn, String fileOut) throws Exception{
String[] comand = new String[]{"ffmpeg", "-i", fileIn, "-acodec", "pcm_s16le", fileOut};
Process process = null;
try {
ProcessBuilder pb = new ProcessBuilder(comand);
pb.redirectErrorStream(true);
process = pb.start();
//Reading from error and standard output console buffer of process. Or it could halts because of nobody
//reads its buffer
BufferedReader reader =
new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
//noinspection StatementWithEmptyBody
while ((line = reader.readLine()) != null) {
System.out.println(line);
//Ignored as we just need to empty the output buffer from process
}
process.waitFor();
} catch (IOException | InterruptedException e) {
throw e;
} finally {
if (process != null)
process.destroy();
}
}
}
}
UPD3:
Sorry, I forgot to notice that I see the work of all these process - they created new converted files but anyway don't exit.
Your application is I/O bound, not CPU bound. If all your files are in the same HDD, then opening simultaneously 300 files will definitely degrade the performance. (that is a likely reason on why you have hundreds of processes waiting).
If I understood correctly, you mentioned that processing 1 file takes some tens of millis? (and this is doing sequential reads - the fastest that your HDD will read a file)
in this case, processing 300 files sequentially should take no more than 30 seconds.
100 millis - process 1 file
1 second - process 10 files
30 second - process 300 files
EDIT
I did 2 simple changes to your sample code (I removed the first loop, then changed the codec) finally I put one song in "ogg" format in "/tmp/origin" directory. now the program works well).
see code below:
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
public class FFMpegConvert {
public static void main(String[] args) throws Exception {
FFMpegConvert f = new FFMpegConvert();
f.processDir("/tmp/origin", "/tmp/destination", false);
}
private void processDir(String dirPath, String dirOutPath, boolean isNewThread) {
File dir = new File(dirPath);
File dirOut = new File(dirOutPath);
if (!dirOut.exists()) {
dirOut.mkdir();
}
for (File f : dir.listFiles()) {
try {
System.out.println(f.getName());
FFmpegRunner fFmpegRunner = new FFmpegRunner(f.getAbsolutePath(), dirOut.getAbsolutePath() + "/" + System.currentTimeMillis() + f.getName());
if (isNewThread) {
new Thread(fFmpegRunner).start();
} else {
fFmpegRunner.run();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class FFmpegRunner implements Runnable {
private String fileIn;
private String fileOut;
FFmpegRunner(String fileIn, String fileOut) {
this.fileIn = fileIn;
this.fileOut = fileOut;
}
#Override
public void run() {
try {
ffmpegconverter(fileIn, fileOut);
} catch (Exception e) {
e.printStackTrace();
}
}
private void ffmpegconverter(String fileIn, String fileOut) throws Exception {
String[] comand = new String[]{"ffmpeg", "-i", fileIn, "-acodec", "copy", fileOut};
Process process = null;
try {
ProcessBuilder pb = new ProcessBuilder(comand);
pb.redirectErrorStream(true);
process = pb.start();
//Reading from error and standard output console buffer of process. Or it could halts because of nobody
//reads its buffer
BufferedReader reader =
new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
//noinspection StatementWithEmptyBody
while ((line = reader.readLine()) != null) {
System.out.println(line);
//Ignored as we just need to empty the output buffer from process
}
process.waitFor();
} catch (IOException | InterruptedException e) {
throw e;
} finally {
if (process != null)
process.destroy();
}
}
}
}
Got it!
In some cases ffmpeg wants to ask me should it override already existed file. In my code I close outputstream of this child process. But as it appears this only closes outputstream for Java but not for the process.
So my solution is to make ffmpeg silent at all: no output from this process with "-v -8", no asking question with default "Yes" "-y".

Detecting terminal command errors in Java

In my Java application I am using the exec() command to call a terminal function:
p = Runtime.getRuntime().exec(command);
p.waitFor();
The call uses the zip and unzip calls. Originally I call:
zip -P password -r encrypted.zip folderIWantToZip
When I call the unzip function through java, I specify the password as the method parameter. If the correct password is specified then the call should unzip the encrypted folder:
unzip -P password encrypted.zip
I want a way to find out if the password entered is incorrect. For example, if password is correct, then the call will correctly unzip the zip file. But I notice that no exception is thrown for an incorrect password. How can I determine this?
You could read the process's ErrorStream and InputStream to determine the process output. Sample code given below
public static void main(String[] args) {
try {
String command = "zip -P password -r encrypted.zip folderIWantToZip";
Process p = Runtime.getRuntime().exec(command);
InputStream is = p.getInputStream();
int waitFor = p.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line;
while ((line = reader.readLine()) != null) {
System.out.println("line:" + line);
}
is = p.getErrorStream();
reader = new BufferedReader(new InputStreamReader(is));
while ((line = reader.readLine()) != null) {
System.out.println("ErrorStream:line: " + line);
}
System.out.println("waitFor:" + waitFor);
System.out.println("exitValue:" + p.exitValue());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
You could use the exitcode to validate the process status as well but it is specific to to program. Normally zero means successfully terminated otherwise abnormal termination.
As per my comment, first thing I would do would be to capture the Process's InputStream and ErrorStream via getInputStream() and getErrorStream(), but especially the latter, the ErrorStream, and check to see what it outputs if the input is in error. Note that these would have to be done in their own thread, else you'll tie up your program. I usually use some type of StreamGobbler class for this. Also, don't ignore the int returned by p.waitFor().
e.g.,
ProcessBuilder pBuilder = new ProcessBuilder(COMMAND);
Process process = null;
try {
process = pBuilder.start();
new Thread(new StreamGobbler("Input", process.getInputStream())).start();
new Thread(new StreamGobbler("Error", process.getErrorStream())).start();
int exitValue = process.waitFor();
System.out.println("Exit Value: " + exitValue);
process.destroy();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (process != null) {
process.destroy();
}
}
And:
class StreamGobbler implements Runnable {
private String name;
private Scanner scanner;
public StreamGobbler(String name, InputStream inputStream) {
this.name = name;
scanner = new Scanner(inputStream);
}
#Override
public void run() {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
System.out.println(name + ": " + line); // or better, log the line
}
scanner.close();
}
}

Java: Redirecting output of .bat file in other text file using exec() method?

Java is new to me.
I am executing a batch file using Runtime.getRuntime.exec(filename.bat) and this batch file executes a commandant encrypt.password -Dvalue=somevalue>log.txt and redirects its output to a log.txt file.
Problem that I am facing is batch file is working fine if I run it manually however when program executes it ,it just creates blank 'log.txt'
Content of mybat.bat batch file is as below:
cd/
c:
cd c:/ant_builds/thinclient
ant encrypt.password -Dvalue=someValue >C:/log.txt
Java code is as below:
Process p=Runtime.getRuntime.exec("C:\mybat.bat");
p.waitFor();
It seems that after creating the log file,meantime command is executing control comes out from process.
I have read almost 50 threads here however did not get the solution. Please help me out.
Use ProcessBuilder to create your process and call redirectOutput(File) to redirect and append output to a file.
Try this code:
public class Test {
ProcessBuilder builder;
Path log;
public Test() {
try
{
log = Paths.get("C:\\log.txt");
if (!Files.exists(log))
{
Files.createFile(log);
}
builder = new ProcessBuilder("ant", "encrypt.password", "-Dvalue=someValue");
builder.directory(Paths.get("C:\\ant_builds\\thinclient").toFile());
builder.redirectOutput(ProcessBuilder.Redirect.appendTo(log.toFile()));
builder.start();
}
catch (IOException e)
{
e.printStackTrace();
}
}
public static void main(String[] args) {
new Test();
}
}
For jdk 1.6 or less, use the following code:
public class Test {
ProcessBuilder builder;
Path log;
Process process;
BufferedReader br;
PrintWriter pw;
Charset charset = Charset.forName("UTF-8");
public Test() {
try {
log = new File("C:\\log.txt");
if (!log.exists()) {
log.createNewFile();
}
builder = new ProcessBuilder("ant", "encrypt.password","-Dvalue=someValue");
builder.directory(new File("C:\\ant_builds\\thinclient"));
builder.redirectErrorStream(true);
process = builder.start();
br = new BufferedReader(new InputStreamReader(process.getInputStream(),charset));
pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(log, true), charset));
(new Thread() {
public void run() {
try {
while (process.isAlive()) {
String s = null;
while ((s = br.readLine()) != null) {
pw.print(s);
pw.flush();
}
}
br.close();
pw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new Test();
}
}
I'm not sure about the order and list of ProcessBuilder arguments so try to play with them to get your code working.
You can also read commands from a common file and redirect output and erros to a sepearate files. Redirect.appendTo is to avoid the process from overiting the existing logs.
Try this code:
try {
File commands = new File("D:/Sample/Commands.txt");
File output = new File("D:/Sample/Output.txt");
File errors = new File("D:/Sample/ErrorsLog.txt");
ProcessBuilder pb = new ProcessBuilder("cmd");
System.out.println(pb.redirectInput());
System.out.println(pb.redirectOutput());
System.out.println(pb.redirectError());
pb.redirectInput(commands);
pb.redirectError(Redirect.appendTo(errors));
pb.redirectOutput(Redirect.appendTo(output));
pb.redirectInput();
pb.redirectOutput();
pb.redirectError();
pb.start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

How to run Linux commands in Java?

I want to create diff of two files. I tried searching for code in Java that does it, but didnt find any simple code/ utility code for this. Hence, I thought if I can somehow run linux diff/sdiff command from my java code and make it return a file that stores the diff then it would be great.
Suppose there are two files fileA and fileB. I should be able to store their diff in a file called fileDiff through my java code. Then fetching data from fileDiff would be no big deal.
You can use java.lang.Runtime.exec to run simple code. This gives you back a Process and you can read its standard output directly without having to temporarily store the output on disk.
For example, here's a complete program that will showcase how to do it:
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) {}
}
}
When compiled and run, it outputs:
line: ./
line: ../
line: .classpath*
line: .project*
line: bin/
line: src/
exit: 0
as expected.
You can also get the error stream for the process standard error, and output stream for the process standard input, confusingly enough. In this context, the input and output are reversed since it's input from the process to this one (i.e., the standard output of the process).
If you want to merge the process standard output and error from Java (as opposed to using 2>&1 in the actual command), you should look into ProcessBuilder.
You can also write a shell script file and invoke that file from the java code. as shown below
{
Process proc = Runtime.getRuntime().exec("./your_script.sh");
proc.waitFor();
}
Write the linux commands in the script file, once the execution is over you can read the diff file in Java.
The advantage with this approach is you can change the commands with out changing java code.
You need not store the diff in a 3rd file and then read from in. Instead you make use of the 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);
}
try to use unix4j. it s about a library in java to run linux command. for instance if you got a command like:
cat test.txt | grep "Tuesday" | sed "s/kilogram/kg/g" | sort
in this program will become:
Unix4j.cat("test.txt").grep("Tuesday").sed("s/kilogram/kg/g").sort();
You can call run-time commands from java for both Windows and 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();
}
}
}
Hope it Helps.. :)
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();
}
The suggested solutions could be optimized using commons.io, handling the error stream, and using Exceptions. I would suggest to wrap like this for use in Java 8 or later:
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);
}
}
if the opening in windows
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);
}
}
ProcessBuilder processBuilder = new ProcessBuilder();
// -- Linux --
// Run a shell command
processBuilder.command("bash", "-c", "ls /home/kk/");
// Run a shell script
//processBuilder.command("path/to/hello.sh");
// -- Windows --
// Run a command
//processBuilder.command("cmd.exe", "/c", "dir C:\\Users\\kk");
// Run a bat file
//processBuilder.command("C:\\Users\\kk\\hello.bat");
try {
Process process = processBuilder.start();
StringBuilder output = new StringBuilder();
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
}
int exitVal = process.waitFor();
if (exitVal == 0) {
System.out.println("Success!");
System.out.println(output);
System.exit(0);
} else {
//abnormal...
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}

Categories