I found several code snippets for running cmd commands through a Java class, but I wasn't able to understand it.
This is code for opening the cmd
public void excCommand(String new_dir){
Runtime rt = Runtime.getRuntime();
try {
rt.exec(new String[]{"cmd.exe","/c","start"});
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
And I found some other links for adding other commands such as cd
http://www.coderanch.com/t/109753/Linux-UNIX/exec-command-cd-command-java
How to open the command prompt and insert commands using Java?
Can anyone help me to understand how to cd a directory such as:
cd C:\Program Files\Flowella
then run other commands on that directory?
One way to run a process from a different directory to the working directory of your Java program is to change directory and then run the process in the same command line. You can do this by getting cmd.exe to run a command line such as cd some_directory && some_program.
The following example changes to a different directory and runs dir from there. Admittedly, I could just dir that directory without needing to cd to it, but this is only an example:
import java.io.*;
public class CmdTest {
public static void main(String[] args) throws Exception {
ProcessBuilder builder = new ProcessBuilder(
"cmd.exe", "/c", "cd \"C:\\Program Files\\Microsoft SQL Server\" && dir");
builder.redirectErrorStream(true);
Process p = builder.start();
BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while (true) {
line = r.readLine();
if (line == null) { break; }
System.out.println(line);
}
}
}
Note also that I'm using a ProcessBuilder to run the command. Amongst other things, this allows me to redirect the process's standard error into its standard output, by calling redirectErrorStream(true). Doing so gives me only one stream to read from.
This gives me the following output on my machine:
C:\Users\Luke\StackOverflow>java CmdTest
Volume in drive C is Windows7
Volume Serial Number is D8F0-C934
Directory of C:\Program Files\Microsoft SQL Server
29/07/2011 11:03 <DIR> .
29/07/2011 11:03 <DIR> ..
21/01/2011 20:37 <DIR> 100
21/01/2011 20:35 <DIR> 80
21/01/2011 20:35 <DIR> 90
21/01/2011 20:39 <DIR> MSSQL10_50.SQLEXPRESS
0 File(s) 0 bytes
6 Dir(s) 209,496,424,448 bytes free
You can try this:-
Process p = Runtime.getRuntime().exec(command);
If you want to perform actions like cd, then use:
String[] command = {command_to_be_executed, arg1, arg2};
ProcessBuilder builder = new ProcessBuilder(command);
builder = builder.directory(new File("directory_location"));
Example:
String[] command = {"ls", "-al"};
ProcessBuilder builder = new ProcessBuilder(command);
builder = builder.directory(new File("/ngs/app/abc"));
Process p = builder.start();
It is important that you split the command and all arguments in separate strings of the string array (otherwise they will not be provided correctly by the ProcessBuilder API).
Here is a more complete implementation of command line execution.
Usage
executeCommand("ls");
Output:
12/27/2017 11:18:11:732: ls
12/27/2017 11:18:11:820: build.gradle
12/27/2017 11:18:11:820: gradle
12/27/2017 11:18:11:820: gradlew
12/27/2017 11:18:11:820: gradlew.bat
12/27/2017 11:18:11:820: out
12/27/2017 11:18:11:820: settings.gradle
12/27/2017 11:18:11:820: src
Code
private void executeCommand(String command) {
try {
log(command);
Process process = Runtime.getRuntime().exec(command);
logOutput(process.getInputStream(), "");
logOutput(process.getErrorStream(), "Error: ");
process.waitFor();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
private void logOutput(InputStream inputStream, String prefix) {
new Thread(() -> {
Scanner scanner = new Scanner(inputStream, "UTF-8");
while (scanner.hasNextLine()) {
synchronized (this) {
log(prefix + scanner.nextLine());
}
}
scanner.close();
}).start();
}
private static SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss:SSS");
private synchronized void log(String message) {
System.out.println(format.format(new Date()) + ": " + message);
}
My example (from real project)
folder — File.
zipFile, filesString — String;
final String command = "/bin/tar -xvf " + zipFile + " " + filesString;
logger.info("Start unzipping: {} into the folder {}", command, folder.getPath());
final Runtime r = Runtime.getRuntime();
final Process p = r.exec(command, null, folder);
final int returnCode = p.waitFor();
if (logger.isWarnEnabled()) {
final BufferedReader is = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while ((line = is.readLine()) != null) {
logger.warn(line);
}
final BufferedReader is2 = new BufferedReader(new InputStreamReader(p.getErrorStream()));
while ((line = is2.readLine()) != null) {
logger.warn(line);
}
}
The easiest way would be to use Runtime.getRuntime.exec().
For example, to get a registry value for the default browser on Windows:
String command = "REG QUERY HKEY_CLASSES_ROOT\\http\\shell\\open\\command";
try
{
Process process = Runtime.getRuntime().exec(command);
} catch (IOException e)
{
e.printStackTrace();
}
Then use a Scanner to get the output of the command, if necessary.
Scanner kb = new Scanner(process.getInputStream());
Note: the \ is an escape character in a String, and must be escaped to work properly (hence the \\).
However, there is no executable called cd, because it can't be implemented in a separate process.
The one case where the current working directory matters is executing an external process (using ProcessBuilder or Runtime.exec()). In those cases you can specify the working directory to use for the newly started process explicitly.
Easiest way for your command:
System.setProperty("user.dir", "C:\\Program Files\\Flowella");
Try this:
Process runtime = Runtime.getRuntime().exec("cmd /c start notepad++.exe");
Once you get the reference to Process, you can call getOutpuStream on it to get the standard input of the cmd prompt. Then you can send any command over the stream using write method as with any other stream.
Note that it is process.getOutputStream() which is connected to the stdin on the spawned process. Similarly, to get the output of any command, you will need to call getInputStream and then read over this as any other input stream.
Stopping and Disabling a service can be done via below code:
static void sdService() {
String[] cmd = {"cmd.exe", "/c", "net", "stop", "MSSQLSERVER"};
try {
Process process = new ProcessBuilder(cmd).start();
process.waitFor();
String line = null;
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
while((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
line = null;
bufferedReader = null;
Process p = Runtime.getRuntime().exec("sc config MSSQLSERVER start= disabled");
p.waitFor();
bufferedReader = new BufferedReader(new InputStreamReader(p.getInputStream()));
while((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
Enabling and Starting a service can be done via below code
static void esService() {
String[] cmd = {"cmd.exe", "/c", "net", "start", "MSSQLSERVER"};
try {
Process p = Runtime.getRuntime().exec("sc config MSSQLSERVER start= auto");
//Process p = Runtime.getRuntime().exec("sc config MSSQLSERVER start= demand");
p.waitFor();
String line = null;
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(p.getInputStream()));
while((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
line = null;
bufferedReader = null;
Process process = new ProcessBuilder(cmd).start();
process.waitFor();
bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
while((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
Executing command from any folder can be done via below code.
static void runFromSpecificFolder() {
try {
ProcessBuilder processBuilder = new ProcessBuilder("cmd.exe", "/c", "cd \"C:\\Users\\himan\\Desktop\\Java_Test_Deployment\\jarfiles\" && dir");
//processBuilder.directory(new File("C://Users//himan//Desktop//Java_Test_Deployment//jarfiles"));
processBuilder.redirectErrorStream(true);
Process p = processBuilder.start();
p.waitFor();
String line = null;
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(p.getInputStream()));
while((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String args[]) {
sdService();
runFromSpecificFolder();
esService();
}
You can't run cd this way, because cd isn't a real program; it's a built-in part of the command-line, and all it does is change the command-line's environment. It doesn't make sense to run it in a subprocess, because then you're changing that subprocess's environment — but that subprocess closes immediately, discarding its environment.
To set the current working directory in your actual Java program, you should write:
System.setProperty("user.dir", "C:\\Program Files\\Flowella");
public class Demo {
public static void main(String args[]) throws IOException {
Process process = Runtime.getRuntime().exec("/Users/******/Library/Android/sdk/platform-tools/adb" + " shell dumpsys battery ");
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = null;
while (true) {
line = in.readLine();
if (line == null) { break; }
System.out.println(line);
}
}
}
The simplest and shortest way is to use CmdTool library.
new Cmd()
.configuring(new WorkDir("C:/Program Files/Flowella"))
.command("cmd.exe", "/c", "start")
.execute();
You can find more examples here.
one of the way to execute cmd from java !
public void executeCmd() {
String anyCommand="your command";
try {
Process process = Runtime.getRuntime().exec("cmd /c start cmd.exe /K " + anyCommand);
} catch (IOException e) {
e.printStackTrace();
}
}
Here the value adder is use of ampersands to batch commands and correct format for change drive with cd.
public class CmdCommander {
public static void main(String[] args) throws Exception {
//easyway to start native windows command prompt from Intellij
/*
Rules are:
1.baseStart must be dual start
2.first command must not have &.
3.subsequent commands must be prepended with &
4.drive change needs extra &
5.use quotes at start and end of command batch
*/
String startQuote = "\"";
String endQuote = "\"";
//String baseStart_not_taking_commands = " cmd /K start ";
String baseStart = " cmd /K start cmd /K ";//dual start is must
String first_command_chcp = " chcp 1251 ";
String dirList = " &dir ";//& in front of commands after first command means enter
//change drive....to yours
String changeDir = " &cd &I: ";//extra & makes changing drive happen
String javaLaunch = " &java ";//just another command
String javaClass = " Encodes ";//parameter for java needs no &
String javaCommand = javaLaunch + javaClass;
//build batch command
String totalCommand =
baseStart +
startQuote +
first_command_chcp +
//javaCommand +
changeDir +
dirList +
endQuote;
System.out.println(totalCommand);//prints into Intellij terminal
runCmd(totalCommand);
//Thread t = Thread.currentThread();
//t.sleep(3000);
System.out.println("loppu hep");//prints into Intellij terminal
}
public static void runCmd(String command) throws Exception {
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(command);
}
}
I am executing grep command from java on a linux file. Its always returning null for the following code.
Process p;
String matchStr="testmatch";
String output = null;
try {
String command = "grep \""+matchStr+"\" "+ filename;
System.out.println("Running command: " + command);
p = Runtime.getRuntime().exec(command);
System.out.println("***********************************");
System.out.println("***********************************");
System.out.println("***********************************");
p.waitFor();
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
while (br.readLine() != null) {
System.out.println("in while loop");
System.out.println("in while loop");
System.out.println("in while loop");
System.out.println(output);
System.out.println("***********************************");
System.out.println("***********************************");
System.out.println("***********************************");
System.out.println("***********************************");
// Process your output here
}
System.out.println("exit: " + p.exitValue());
p.destroy();
} catch (Exception e) {
e.printStackTrace();
}
If i grep it directly it shows output but from java it never gets into while loop.
Please suggest whats wrong here.
The problem is that you do not write anything to output so it stays null. I guess you have to rewrite your while loop like this
while ((output = br.readLine()) != null) {
// Process your output here
}
Take a note that this syntax is discouraged by most style check due to it's abmiguity
Also it's a good idea to place p.waitFor() after while loop so grep would not hang on flushig std(err|out).
UPDATE
Also it is a good idea to use ProcessBuilder (available since java-7) instead of Runtime.getRuntime().exec(...) because you will have more control over the process i.e
final ProcessBuilder builder = new ProcessBuilder();
builder.command("grep", matchStr, filename);
// redirect stderr to stdout
builder.redirectErrorStream(true);
final Process process = builder.start();
BufferedReader br = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String output = null;
while ((output = br.readLine()) != null) {
System.out.println(output);
// Process your output here
}
process.waitFor();
After turning your code into a https://stackoverflow.com/help/mcve it works for me.
Here the file does not exist:
robert#habanero:~$ rm /home/robert/greptest.txt
robert#habanero:~$ javac GrepTest.java && java GrepTest
Running command: grep test /home/robert/greptest.txt
exit: 2
Now the file does exist but does not contain the text to be found:
robert#habanero:~$ echo not found > /home/robert/greptest.txt
robert#habanero:~$ javac GrepTest.java && java GrepTest
Running command: grep test /home/robert/greptest.txt
exit: 1
Now the file exists and contains the text:
robert#habanero:~$ echo test this > /home/robert/greptest.txt
robert#habanero:~$ javac GrepTest.java && java GrepTest
Running command: grep test /home/robert/greptest.txt
test this
exit: 0
Here is the code:
import java.io.*;
public class GrepTest {
public static void main(String[] args) throws Exception {
String command = "grep test /home/robert/greptest.txt";
System.out.println("Running command: " + command);
Process p = Runtime.getRuntime().exec(command);
p.waitFor();
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String output;
while ((output = br.readLine()) != null) {
System.out.println(output);
}
System.out.println("exit: " + p.exitValue());
p.destroy();
}
}
I was recently struggling with a similar issue, and I believe I the solution I found is an answer also to your problem (though your question is a bit malformed as others have pointed out).
The issue pertrains to the quote marks around your search string,
\""+matchStr+"\"
The java exec command will literally deliver these to the grep command, and instead of searching for matchStr, grep will be looking for "matchStr", and the results will not be what you are expecting.
This applies also in case one is executing the command as an array like
final Process process = Runtime.getRuntime().exec(new String[] { "grep", "-C1000", searchString, fileName } );
Pass the plain searchString without including quotation marks into the string.
I want to run NS2(which is an external program in linux) commands through java, using ProcessBuilder
when I get the ns command not found error
/home/maria/Documents/test.sh: line 4: ns: command not found
Execution failed.
org.apache.commons.exec.ExecuteException: Process exited with an error: 127 (Exit value: 127)
at org.apache.commons.exec.DefaultExecutor.executeInternal(DefaultExecutor.java:404)
at org.apache.commons.exec.DefaultExecutor.execute(DefaultExecutor.java:166)
at org.apache.commons.exec.DefaultExecutor.execute(DefaultExecutor.java:153)
at test.opencmd.runScript(opencmd.java:18)
at test.opencmd.main(opencmd.java:30)
my java code is
package test;
import java.io.*;
public class test2 {
public static void main(String args[]) {
String s = null;
try {
// run the Unix "};
//System.out.print(System.getProperty("user.home"));
Process p = Runtime.getRuntime().exec( "ns /home/maria/ns-allinone-2.35/ns-2.35/indep-utils/cmu-scen-gen && cbrgen.tcl -type cbr -nn 10 -seed 1 -mc 5 -rate 5.0");
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(p.getErrorStream()));
// read the output from the command
System.out.println("Here is the standard output of the command:\n");
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);
}
System.exit(0);
}
catch (IOException e) {
System.out.println("exception happened - here's what I know: ");
e.printStackTrace();
System.exit(-1);
}
}
}
I guess i am not making a right program call.
I guess the terminal/session which jvm executes your command doesn't know where/what is 'ns' [i.e: your executable library]
Try executing by giving the full path to your library, like
Process p = Runtime.getRuntime().exec( "/fullpath/ns /home/maria/ns-allinone-2.35/ns-....
Java is unable to find 'ns'. To tell that to Java program you have to mention full path as below:
Process p = Runtime.getRuntime().exec("/home/maria/ns-allinone-2.35/ns-2.35/indep-utils/cmu-scen-gen/setdest/setdest -v 2 -n 50 -p 2.0 -s 10.0 -t 200 -x 500 -y 500 -m 2 -M 15");
Process p = Runtime.getRuntime().exec("/home/maria/ns-allinone-2.35/bin/ns /home/maria/ns-allinone-2.35/ns-2.35/indep-utils/cmu-scen-gen/cbrgen.tcl -type cbr -nn 10 -seed 1 -mc 5 -rate 5.0");
if NS is a java program then use java ns as below.
Runtime.getRuntime().exec( "java ns /home/maria/ns-allinone-2.35/ns-2.35/indep-utils/cmu-scen-gen && cbrgen.tcl -type cbr -nn 10 -seed 1 -mc 5 -rate 5.0");
sorry when I tag ffmpeg because I couldn't tag MP4Box.But I have proplem with excuted with ffmpeg via javacode too.
I read at How to execute cmd commands via Java but i can't find my proplem.
I'm tested commands in cmd, it was ok:
MP4Box -dash 10000 -dash-profile live -segment-name output- seg -rap
-bs-switching no input.mp4
but when i executed cmd via java code , i get error:
Error - only one input file found as argument, please check usage
Below is my code, has something wrong?
package com.uit.reformatvideo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.logging.Logger;
public class ExecuteComandToFormatVideo {
public final static String LINK_MP4BOX = "C:/MP4Box/Tools/MP4Box.exe";
public final static String CREATE_MPD_ECLIPSE = "mp4box -dash 10000 -frag 1000 -rap -bs-switching no";
public final static String CREATE_MPD_IE = "MP4Box -dash 10000 -dash-profile live -segment-name output-seg -rap -bs-switching no";
private static final Logger log = Logger.getLogger(ExecuteComandToFormatVideo.class.getName());
public static void main(String[] args) throws IOException, InterruptedException {
String s = null;
try {
// run the Unix "ps -ef" command
// using the Runtime exec method:
String lsCmd[] = new String [2];
lsCmd[0] = LINK_MP4BOX;
lsCmd[1] = "MP4Box -dash 10000 -dash-profile live -segment-name output-seg -rap -bs-switching no input.mp4";
Process p = Runtime.getRuntime().exec(lsCmd);
p.waitFor();
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(p.getErrorStream()));
// read the output from the command
System.out.println("Here is the standard output of the command:\n");
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);
}
System.exit(0);
}
catch (IOException e) {
System.out.println("exception happened - here's what I know: ");
e.printStackTrace();
System.exit(-1);
}
}
}
Here was out put:
Here is the standard output of the command:
Here is the standarderror of the command (if any): Error - only one
input file found as argument, please check usage
sorry because my English is bad. I created a bat file which included command such as CMD, then I used Runtime.getRuntime().exec(url+name+".bat");
to execute the bat file. This is my solution.
My bat file:
cd C:/MP4Box/Tools/
MP4Box
MP4Box -dash 10000 -dash-profile live -segment-name output-seg -rap -bs-switching no "C:\Users\ducth\Desktop\New folder (2)\SharingVideo\src\main\webapp\resources\video\output.mp4"
I am trying to run wc -l filename command using Runtime.getRuntime().exec(command) and get the total number of lines. But it is not working.
Here is my code :
private String executeCommand(String command) {
StringBuffer output = new StringBuffer();
Process p;
try {
System.out.println(command);
p = Runtime.getRuntime().exec(command);
BufferedReader reader = new BufferedReader(
new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine())!= null) {
output.append(line.split("\\s+")[0] + "\n");
}
int exc = p.waitFor();
System.out.println(exc);
} catch (Exception e) {
e.printStackTrace();
}
return output.toString();
}
exc (the exit value) is coming out zero. When I am printing the command which I am passing, it gives the right command. I have also tried to copy that command and run it in Linux. It's working, but not through program.
Command which I am passing to command variable in the functionexecuteCommand is:
wc -l < log1
Total number of lines it contains around 4597110. Also I dont want the size of file in bytes, I have to get the total number of lines only.
An easier alternative for getting the lines (with Java 8).
long lines = Files.lines(Paths.get("foo.txt")).count();
Kayaman has a much better answer if you're on Java 8 or better. If, however, you're stuck on an earlier iteration, see below.
You see this bit of code that you use for evaluating the output of wc:
while ((line = reader.readLine())!= null) {
output.append(line.split("\\s+")[0] + "\n");
}
That's remarkably similar to the code that could just read the file directly and count the number of lines.
So I'm not entirely certain why you think there's a need to call an external program to do this task, especially as it degrades the portabilty of your code.
Just open the file and read the lines, adding one to a counter for each line. And there you have it, the line count.
See, for example, the following file:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.File;
public class Test
{
static private int getLineCount(String fspec) {
String line;
int count = 0;
try {
BufferedReader reader = new BufferedReader(
new FileReader(new File(fspec)));
while ((line = reader.readLine())!= null)
count++;
} catch (Exception e) {
count = -1;
}
return count;
}
public static void main(String[] args) {
System.out.println (getLineCount("/tmp/tempfile"));
}
}
Running this gives 140 as does the output from wc -l:
pax> wc -l /tmp/tempfile
140 /tmp/tempfile
Looks like you don't pass correct path to the file, try this when you run method:
URL fileName = ClassLoader.getSystemClassLoader().getResource("filename");
System.out.println(executeCommand("wc -l " + fileName.getPath()));
Try using Process in the following way:
ProcessBuilder pb = new ProcessBuilder("wc", "-l");
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));){
Process process = pb.start();
while (reader.readLine() != null){
// you need to figure out in which line the
// relevant output is and parse that to int
// just look at some sample outputs of wc -l
}
int err = process.waitFor();
if(err!=0) {
// your code for processing the number of lines goes here
// the command finished without error
}
else {
// your code here in case the command had an error
}
} catch (Exception e){
// catch an Exception like IOException or InterruptedException here
}
Basically the Reader will read the output from the command that would go to the terminal when executing the command there.
You can use apache common io FileUtils.readLines(File file)
FileUtils.readLines(new File("filename.txt")).size()