I am searching files based on extension. Now for each file found, want to run a command:
Lets assume file found: C:\Home\1\1.txt. My exe exists in: C:\Home\Hello.exe
I would like to run command something like: "C:\Home\Hello.exe C:\Home\1\1.txt"
similarly for C:\Home\ABC\2.txt - "C:\Home\Hello.exe C:\Home\ABC\2.txt"
Kindly help me how to pass a searched file as an input to execute a command.
Thanks,
Kino
You can use below program as a base and then customize further as per your rqeuirement
public class ProcessBuildDemo {
public static void main(String [] args) throws IOException {
String[] command = {"CMD", "/C", "dir"}; //In place of "dir" you can append the list of file paths that you have
ProcessBuilder probuilder = new ProcessBuilder( command );
//You can set up your work directory
probuilder.directory(new File("c:\\xyzwsdemo")); //This is the folder from where the command will be executed.
Process process = probuilder.start();
//Read out dir output
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
System.out.printf("Output of running %s is:\n",
Arrays.toString(command));
while ((line = br.readLine()) != null) {
System.out.println(line);
}
//Wait to get exit value
try {
int exitValue = process.waitFor();
System.out.println("\n\nExit Value is " + exitValue);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Lets get you started:
Filter files using: FilenameFilter:
http://docs.oracle.com/javase/7/docs/api/java/io/FilenameFilter.html
Sample:
http://www.java-samples.com/showtutorial.php?tutorialid=384
And after you have got the files:
Use ProcessBuilder to execute:
http://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html
Sample:
http://www.xyzws.com/Javafaq/how-to-run-external-programs-by-using-java-processbuilder-class/189
If you are running your app from the command line (e.g. windows cmd), and your program name is Hello.java, only thing you have to do is to put in the argument, just like you did in your example. So it looks something like:
java Hello C:\Home\1\1.txt
I did not use exe, since this is an example, and the question is tagged with "java" tag.
Your Hello.java MUST have a main method that looks like this:
public static void main(String ... args) {
}
The parameter args are the actual parameters you enter in the command line. So to get the file name, you would have to do this:
public static void main(String ... args) {
String fileName= args[0];
}
And that's it. Later on, you can do with that whatever you want, i.e. open and edit a file:
File file= new File(fileName);
//do whatever with that file.
This code will help you
public static void main(String args[]) {
String filename;
try {
Runtime rt = Runtime.getRuntime();
filename = "";//read the file na,e
Process pr = rt.exec("C:\\Home\\Hello.exe " + filename );
BufferedReader input = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line=null;
while((line=input.readLine()) != null) {
System.out.println(line);
}
int exitVal = pr.waitFor();
System.out.println("Error "+exitVal);
} catch(Exception e) {
System.out.println(e.toString());
e.printStackTrace();
}
}
Related
I want to communicate with the linux terminal with java code. I want to store the output and work with it. I implemented the code below following the instructions in given link.
I would expect the complete terminal output of help. But neither for the standard commands, nor for the mosquitto commands I get anything from the input stream. Where is the mistake? Or are you supposed to do it completely differnt?
Stackoverflow link: how to run a command at terminal from java program?
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class LinuxInputStream
{
public static void main(String[] args)
{
// Linux Terminal
String prefix = "/bin/bash";
String terminalCommand = "help";
String mosquittoCommand = "mosquitto --help";
ProcessBuilder pb1 = new ProcessBuilder(
new String[] {prefix, terminalCommand});
ProcessBuilder pb2 = new ProcessBuilder(
new String[] {prefix, mosquittoCommand});
try
{
executeCommand(pb1);
}
catch (IOException e)
{
System.out.println("IO Error in Terminal Command execution!");
e.printStackTrace();
}
try
{
executeCommand(pb2);
}
catch (IOException e)
{
System.out.println("IO Error in Mosquitto Command execution!");
e.printStackTrace();
}
}
private static void executeCommand(ProcessBuilder pb) throws IOException
{
Process terminalCommandProcess = pb.start();
InputStream inputStream = terminalCommandProcess.getInputStream();
BufferedReader br = new BufferedReader(
new InputStreamReader(inputStream));
String line;
int i = 0;
while ((line = br.readLine()) != null)
{
System.out.println("Line: " + line);
i++;
}
if (i == 0) System.out.println("Nothing read from input stream");
}
}
Output:
Nothing read from input stream Nothing read from input stream
Just found the solution immidiatly after the post: The "-c" part is missing. Correct code snippet is:
// Linux Terminal
String prefix = "/bin/bash";
String c = "-c";
String terminalCommand = "help";
String mosquittoCommand = "mosquitto --help";
ProcessBuilder pb1 = new ProcessBuilder(
new String[] {prefix, c, terminalCommand});
ProcessBuilder pb2 = new ProcessBuilder(
new String[] {prefix, c, mosquittoCommand});
I want to write a program which executes JARs and gets their output.
When the JAR program has only a print statement it works fine, but when it asks for input during execution, the program freezes.
Code of the JAR file program:
import java.util.*;
public class demo {
public static void main(String r[]) {
Scanner sc = new Scanner(System.in);
System.out.println("Hello ...");
System.out.println("please enter the number :");
int i = sc.nextInt();
System.out.println(" number : " + i);
}
}
Code of the original program which runs the JAR files:
public class jartorun {
public static void main(String arg[]) throws IOException {
String t = "javaw -jar D:\\jarcheck\\temp.jar";
Process p = Runtime.getRuntime().exec(t);
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = input.readLine()) != null) {
System.out.print(line + "\n");
}
input.close();
}
}
I can give input to the JAR using process.getOutputStream(), but how would I use it so I can create a program which can give input to a JAR and read its output simultaneously?
If you want to run stuff outside the VM use the ProcessBuilder. Works fine for me and you can inherit the IO Stream.
ProcessBuilder builder = new ProcessBuilder("./script.sh",
"parameter1");
builder.directory(new File("/home/user/scripts/"));
builder.inheritIO();
try {
Process p = builder.start();
p.waitFor();
// Wait for to finish
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
}
This should also work with Windows batch scripts and paths.
(haven't tried the input though)
You can use p.getOutputStream() to provide input to the launched process.
I am trying to figure out how to reference a python file so that I can execute it within a Java GUI Jar. It needs to be a portable solution, so using absolute paths will not work for me. I have listed my project structure below, and have included the code for how I am trying to execute the python script..I have read things about using resources, but I have been unable to implement this successfully. I appreciate any help you can provide!
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
try {
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec("python /scripts/script.py");
BufferedReader bfr = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line = "";
while((line = bfr.readLine()) != null)
System.out.println(line);
}
catch(Exception e) {
System.out.println(e.toString());
}
}
--OneStopShop (Project)
--Source Packages
--images
--onestopshop
--Home.java
--scripts
--script.py
Starting a file path with a / means you want to start at the root of your file system.
Your code worked for me by simply removing that leading slash:
public static void main(String[] args) {
try {
File python = new File("scripts/script.py");
System.out.println(python.exists()); // true
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec("python scripts/script.py"); // print('Hello!')
BufferedReader bfr = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line = "";
while((line = bfr.readLine()) != null)
System.out.println(line);
}
catch(Exception e) {
System.out.println(e.toString());
}
}
// true
// Hello!
// Process finished with exit code 0
The reason why putting a wrong file did not show an error is because this java code only displays the input stream (getInputStream()), not the error stream (getErrorStream()):
public static void main(String[] args) {
try {
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec("python scripts/doesnotexist.py");
BufferedReader bfr = new BufferedReader(new InputStreamReader(pr.getErrorStream()));
String line = "";
while((line = bfr.readLine()) != null)
System.out.println(line);
}
catch(Exception e) {
System.out.println(e.toString());
}
}
// python: can't open file 'scripts/doesnotexist.py': [Errno 2] No such file or directory
// Process finished with exit code 0
try {
String str;
Process process = Runtime.getRuntime().exec("bash /home/abhishek/workspace/Pro/run");
InputStream isout = process.getInputStream();
InputStreamReader isoutr = new InputStreamReader(isout);
BufferedReader brout = new BufferedReader(isoutr);
while ((str = brout.readLine()) != null) {
System.out.println(str);
}
} catch (IOException e) {
e.printStackTrace();
}
The Code has issues with getting the InputStream from the Process,
because if I run the Shell script from my Terminal it runs completely fine,
but if I Run the Script like this,the str is always null,
I am using this code to get the output of the Shell Script directly into Java instead writing the Script Output in the File
Is there any other way to achieve this,or how can I get the issue solved using the current approach
I think something returned through the error stream, so you can try to check something from the Process.getErrorStream().
You should also wait for the created process to prevent your main program completes before it. Use Process.waitFor();
public class TestMain {
private static final String BASH_CMD = "bash";
private static final String PROG = "/home/abhishek/workspace/Pro/run";
private static final String[] CMD_ARRAY = { BASH_CMD , PROG };
public static void main(String[] args) {
new Thread(new Runnable() {
public void run() {
BufferedReader reader = new BufferedReader(new InputStreamReader(
System.in));
String command = null;
try {
while ((command = reader.readLine()) != null) {
System.out.println("Command Received:" + command);
}
} catch (Exception ex) {
ex.printStackTrace();
// failed to listening command
}
}
}).start();
Process process = null;
try {
ProcessBuilder processBuilder = new ProcessBuilder(CMD_ARRAY);
process = processBuilder.start();
InputStream inputStream = process.getInputStream();
setUpStreamGobbler(inputStream, System.out);
InputStream errorStream = process.getErrorStream();
setUpStreamGobbler(errorStream, System.err);
System.out.println("never returns");
process.waitFor();
} catch (IOException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
public static void setUpStreamGobbler(final InputStream is, final PrintStream ps) {
final InputStreamReader streamReader = new InputStreamReader(is);
new Thread(new Runnable() {
public void run() {
BufferedReader br = new BufferedReader(streamReader);
String line = null;
try {
while ((line = br.readLine()) != null) {
ps.println("process stream: " + line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
Edit you /home/abhishek/workspace/Pro/run if it is a shell and add the following line on top.
#!/usr/bin/bash
and give required execute permissions to /home/abhishek/workspace/Pro/run.
Then use the following line
Process process = Runtime.getRuntime().exec("/home/abhishek/workspace/Pro/run");
Now if the run program prints anything you should see it in the output.
Your code looks fine. So, I believe that problem is either in command line you are using (bash /home/abhishek/workspace/Pro/run) or in your script itself.
I'd suggest you to perform the following steps:
try to run some well-known command instead of your script. For example pwd. Check that your code that is reading from input stream works correctly.
Now try to simplify your script. Create script run1 that just runs the same pwd. Now run this script from java and see that it is working. BTW you do not have to run it as bash yourscript. You can directly run it without bash prefix
If all this works start to move from simple to your real script step-by-step. I believe you will find your mistake. Probably your script cannot start for some environment related problems.
Possible problem is by the time you obtain inputStram the sub-process is not ready
Try
Process process = Runtime.getRuntime().exec("bash /home/abhishek/workspace/Pro/run");
InputStream isout = process.getInputStream();
process.waitFor()
Try something like this:
String[] runCommand = new String[3];
runCommand[0] = "sh";
runCommand[1] = "-c";
runCommand[2] = "bash /home/abhishek/workspace/Pro/run";
Process process = runtime.exec(runCommand);
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = reader.readLine();
reader.close();
After multiple readings of the source code for the unix implementation of Process at https://github.com/AdoptOpenJDK/openjdk-jdk11/blob/master/src/java.base/unix/classes/java/lang/ProcessImpl.java it seems that the standard redirects will always swallow to a ProcessBuilder.NullInputStream:
if (redirects[1] == Redirect.PIPE) {
std_fds[1] = -1;
}...
and
stdout = (fds[1] == -1 || forceNullOutputStream) ?
ProcessBuilder.NullInputStream.INSTANCE :
new ProcessPipeInputStream(fds[1]);
(The same code repeats for stdIn, stdOut and stdErr streams)
The only workaround I have found, which feels very clumsy is to use a temp File:
File stdOutTmp; // create and destroy however you see fit
ProcessBuilder pb = ...;
pb.redirectOutput(ProcessBuilder.Redirect.to(stdOutTmp));
...
There are other static factory methods (Redirect.appendTo(File) to append to an existing file rather than overwrite an existing file, and Redirect.from(File) for stdIn)
In Java, I want to be able to execute a Windows command.
The command in question is netsh. This will enable me to set/reset my IP address.
Note that I do not want to execute a batch file.
Instead of using a batch file, I want to execute such commands directly. Is this possible?
Here is my implemented Solution for Future Reference:
public class JavaRunCommand {
private static final String CMD =
"netsh int ip set address name = \"Local Area Connection\" source = static addr = 192.168.222.3 mask = 255.255.255.0";
public static void main(String args[]) {
try {
// Run "netsh" Windows command
Process process = Runtime.getRuntime().exec(CMD);
// Get input streams
BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(process.getErrorStream()));
// Read command standard output
String s;
System.out.println("Standard output: ");
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
// Read command errors
System.out.println("Standard error: ");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
} catch (Exception e) {
e.printStackTrace(System.err);
}
}
}
Runtime.getRuntime().exec("netsh");
See Runtime Javadoc.
EDIT: A later answer by leet suggests that this process is now deprecated. However, as per the comment by DJViking, this appears not to be the case: Java 8 documentation. The method is not deprecated.
Use ProcessBuilder
ProcessBuilder pb=new ProcessBuilder(command);
pb.redirectErrorStream(true);
Process process=pb.start();
BufferedReader inStreamReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
while(inStreamReader.readLine() != null){
//do something with commandline output.
}
You can run the command with Runtime.getRuntime().exec("<command>") (eg. Runtime.getRuntime().exec("tree")). But, this will only run executables found in path, not commands like echo, del, ... But only stuff like tree.com, netstat.com, ... To run regular commands, you will have to put cmd /c before the command (eg Runtime.getRuntime().exec("cmd /c echo echo"))
public static void main(String[] args) {
String command="netstat";
try {
Process process = Runtime.getRuntime().exec(command);
System.out.println("the output stream is "+process.getOutputStream());
BufferedReader reader=new BufferedReader( new InputStreamReader(process.getInputStream()));
String s;
while ((s = reader.readLine()) != null){
System.out.println("The inout stream is " + s);
}
} catch (IOException e) {
e.printStackTrace();
}
}
This works.
Runtime#exec().