I am trying to use Runtime to run a simple cmd script. Below I have two examples. When I run the command strings by hand in a cmd shell, they produce the desired result. When I run this program, command 1 works, and command 2 does not. Is there any particular reason why the second command wouldn't work through java while the first does?
No error messages or exceptions.
EDIT: The second command works if I add an execution log, i.e. change it to the line below. Why would that be?
String cmd2 = "C:/Users/evans/Documents/NetBeansProjects/Repricer/RunDownload.cmd >> log.txt";
The execution log is this:
// Execution log
C:\Users\evans\Documents\NetBeansProjects\Test>"C:\Program Files (x86)\Microsoft Office\root\Office16\MSACCESS.EXE" "C:\Users\evans\Documents\Book Business\Building Reports\Book Business.accdb" /x Download
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Test {
public static void main(String[] args) {
try {
// 1
String cmd = "wscript C:/Users/evans/Documents/NetBeansProjects/Repricer/RunExcel.vbs DownloadExcel";
Runtime.getRuntime().exec( new String[] {"cmd.exe", "/c", cmd} );
// 2
String cmd2 = "C:/Users/evans/Documents/NetBeansProjects/Repricer/RunDownload.cmd";
Runtime.getRuntime().exec( new String[] {"cmd.exe", "/c", cmd2} );
} catch (IOException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Related
I dont know why, but I can only execute a very small pallet of commands on my Raspberry 3B from code (I cane even execute echo). For some reason, 99% of the commands that you would normally be able to do in the terminal itself, you cant do from code.
Example: I execute this java code:
Runtime.getRuntime().exec("echo hi");
And I get this:
`java.io.IOException: Cannot run program "echo hi": error=2, No such file or directory
Is there a PATH configuration that I dont have access to in java code? why cant I execute any commands to the raspberry pi from code?
I've written some example that uses the exec() call. There are other methods to start processes from within Java (ProcessBuilder is the keyword here), but this example is relatively easy to understand:
import java.util.*;
import java.io.*;
import java.text.*;
public class X {
public static void main(String argv[])
{
String args[] = { "/bin/bash", "-c", "uptime" };
try {
Process p = Runtime.getRuntime().exec(args);
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = in.readLine();
while (line != null) {
System.out.println("Found: " + line);
line = in.readLine();
}
} catch (Exception e) {
System.err.println("Some error occured : " + e.toString());
}
}
}
Basically the program executes the command line /bin/bash -c uptime; just an uptime would have done the same, but I wanted to show how to work with command line arguments for the program to start.
Am trying to get a series of commands on git bash one after the other. I can open the terminal through the code but after that wasn't successful with entering anything. For instance this is the code I tried
String [] args = new String[] {"C:\\Program Files\\Git\\git-bash.exe"};
String something="hi how are you doing";
try {
ProcessBuilder p = new ProcessBuilder();
var proc = p.command(args).start();
var w = new BufferedWriter(new OutputStreamWriter(proc.getOutputStream()));
w.write(something);
} catch (IOException ioException){
System.out.println(ioException);
}
Please let know how to be able to do enter a series of commands into git bash through the code.
The problem is that the command git-bash.exe opens the terminal window but the window's input is still the keyboard, so trying to write to the OutputStream that is returned by method getOutputStream(), in class Process does nothing. Refer to this question.
As an alternative, I suggest using using ProcessBuilder to execute a series of individual git commands. When you do that, your java code gets the command output.
Here is a simple example that displays the git version.
import java.io.IOException;
public class ProcBldT4 {
public static void main(String[] args) {
// C:\Program Files\Git\git-bash.exe
// C:\Program Files\Git\cmd\git.exe
ProcessBuilder pb = new ProcessBuilder("C:\\Program Files\\Git\\cmd\\git.exe", "--version");
pb.inheritIO();
try {
Process proc = pb.start();
int exitStatus = proc.waitFor();
System.out.println(exitStatus);
}
catch (IOException | InterruptedException x) {
x.printStackTrace();
}
}
}
When you run the above code, the git version details will be written to System.out.
Also, if the git command fails, the error details are written to System.err.
You need to repeat the code above for each, individual git command that you need to issue.
How do you have java run commands on Mac? I see some examples of complex commands that is hard to follow. If I wanted to run a simple echo command from java, how would I do that? Not using osascript yet. Just want to see how you would send an echo from java to terminal.
public static void main(String[] args) throws IOException {
ProcessBuilder x = new ProcessBuilder("echo"," hi");
x.start();
}
This is the code I tried, but it does not work.
I think this question can help people who are trying to learn the basics of ProcessBuilder.
I am on Windows so the below code uses Windows echo. I hope you know the Mac echo command so that you can replace my command with yours.
import java.io.IOException;
import java.lang.ProcessBuilder;
public class PrcBldT2 {
public static void main(String[] args) {
// This command is for Windows operating system.
// For MacOS, try: new ProcessBuilder("echo", "hi")
ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", "echo", "hi");
pb.redirectError(ProcessBuilder.Redirect.INHERIT);
pb.redirectOutput(ProcessBuilder.Redirect.INHERIT);
try {
Process p = pb.start();
int result = p.waitFor();
System.out.println("Exit status = " + result);
}
catch (IOException | InterruptedException x) {
x.printStackTrace();
}
}
}
Note that each word in the command is a separate string. The echo command output will be redirected to System.out.
I am writing a java code that has the purpose of opening a URL on youtube using Google Chrome but I have been unsuccessful in understanding either method. Here is my current attempt at it.
import java.lang.ProcessBuilder;
import java.util.ArrayList;
public class processTest
{
public static void main(String[] args)
{
ArrayList<String> commands = new ArrayList<>();
commands.add("cd C:/Program Files/Google/Chrome/Application");
commands.add("chrome.exe youtube.com");
ProcessBuilder executeCommands = new ProcessBuilder( "C:/WINDOWS/System32/WindowsPowerShell/v1.0/powershell.exe", "cd C:/Program Files/Google/Chrome/Application", "chrome.exe youtube.com");
}
}
It compiles OK, but nothing happens when I run it. What is the deal?
As stated by Jim Garrison, ProcessBuilder's constructor only executes a single command. And you do not need to navigate through the directories to reach the executable.
Two possible solutions for your problem (Valid for my Windows 7, be sure to replace your Chrome path if neccesary)
With ProcessBuilder using constructor with two parameters: command, argument (to be passed to command)
try {
ProcessBuilder pb =
new ProcessBuilder(
"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe",
"youtube.com");
pb.start();
System.out.println("Google Chrome launched!");
} catch (IOException e) {
e.printStackTrace();
}
With Runtime using method exec with one parameter, a String array. First element is the command, following elements are used as arguments for such command.
try {
Runtime.getRuntime().exec(
new String[]{"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe",
"youtube.com"});
System.out.println("Google Chrome launched!");
} catch (Exception e) {
e.printStackTrace();
}
you shoule invoke start method to execute the operation, like this:
ProcessBuilder executeCommands = new ProcessBuilder( "C:/WINDOWS/System32/WindowsPowerShell/v1.0/powershell.exe", "cd C:/Program Files/Google/Chrome/Application", "chrome.exe youtube.com");
executeCommands.start();
I've been struggling for a while now with this problem and i can't seem to fix it. i have tried ProcessBuilder for executing the custom command on linux terminal but its not working
Actually i have two .sh file setProto.sh and setTls.sh file which is used to set the environment.So for executing the command i need to run these two file first for each instance of linux terminal.Only then we can be able to run the custom command anloss on the same instance of linux terminal in which .sh file supposed to run.For some reason i'm not able to make it work what is the mistake in my code ? Here's the code.
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.ProcessBuilder.Redirect;
public class EngineTest {
public static void main(String[] args) {
try {
ProcessBuilder builder = new ProcessBuilder(
"/. setProto.sh",
"/. setTls.sh",
"/anloss -i ${TOOL_INPUT}/census_10000_col5.csv -d ${TOOL_DEF}/attr_all_def.txt -q k=14,dage=2 -g ${TOOL_RES}/census_100_col8_gen.csv");
builder.directory(new File(System.getenv("HOME") + "/PVproto/Base"));
File log = new File("log");
builder.redirectErrorStream(true);
builder.redirectOutput(Redirect.appendTo(log));
Process process = builder.start();
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String line = "";
String output = "";
while ((line = bufferedReader.readLine()) != null) {
output += line + "\n";
}
System.out.println(output);
int exitValue = process.waitFor();
System.out.println("\n\nExit Value is " + exitValue);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Process does not by default execute in the context of a shell; therefore your shell scripts cannot be executed the way you tried.
ProcessBuilder pb =
new ProcessBuilder( "/bin/bash",
"-c",
". setProto.sh && . setTls.sh && /anloss -i ${TOOL_INPUT}/census_10000_col5.csv -d ${TOOL_DEF}/attr_all_def.txt -q k=14,dage=2 -g ${TOOL_RES}/census_100_col8_gen.csv" );
I am not sure about /anloss - it's unusual for a command to be in root's home /. (Also, the /. you had there in front of the shell scripts - what should they achieve?)
Later
Make sure to replace /anloss with an absolute pathname or a relative pathname relative to $HOME/PVproto/Base, e.g., if it is in this directory, use ./anloss, if it is in $HOME/PVproto/Base/SomeSub, use SomeSub/anloss, etc.
Also, if setProto.sh and . setTls.sh are not in $HOME/PVproto/Base, use an appropriate absolute or relative pathname. If they are, use ./setProto.sh and ./setTls.sh to avoid dependency on the setting of environment variable PATH.
I think you need to use Runtime.exec() for executing the commands on linux. I suppose you are executing your java code on linux machine where linux scripts needs to be run.
Below code snippet will help you in resolving it.
Process process = Runtime.getRuntime().exec(scriptWithInputParameters);
int exitCode = process.waitFor();
if (exitCode == 0) {
System.out.println("Executed successfully");
}
else {
System.out.println("Failed ...");
}
Please note you need to handle error and output stream in different threads to avoid buffer overflow.
If the above works for you then this article will help you further