How would I go about executing a .SH file (this is localhost, no remote connection or anything)? I've seen lots of Runtime.exec and other things when I searched but those didn't seem to work.
This is Java 6. Also if it matters, all the SH is doing is moving two folders around.
Thanks!
You could use ProcessBuilder
ProcessBuilder pb = new ProcessBuilder("myshell.sh", "myArg1", "myArg2");
Process p = pb.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null)
{
System.out.println(line);
}
You may also give some consideration to the JSch library if you do not want to make your code platform-dependent by directly invoking OS commands.
Related
I want to run a .sh file using java. I want a terminal to be opened and then I can execute another commands in the same terminal and finally destroy it.
I already used ProcessBuilder but I could not accomplish this.
My piece of code:
ProcessBuilder pb = new ProcessBuilder("/home/omar/ros_ws/baxter2.sh");
Process p = pb.start();
This method used to work in another code, but I don't know why it's not working in mine.
Thanks in advance
How do you know that it doesn't execute? Maybe you just aren't seeing its result. You should get p.getInputStream() after executing and print in your console, like:
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null)
{
System.out.println(line);
}
Also if you're using jdk 7+, try:
pb.redirectOutput(Redirect.INHERIT);
pb.redirectError(Redirect.INHERIT);
Process p = pb.start();
Does your program output an error, or is your program not interacting with the file?
I would suggest trying the directory method within ProcessBuilder.
Process p = null;
ProcessBuilder pb = new ProcessBuilder("baxter2.sh");
pb.directory("/home/omar/ros_ws");
p = pb.start();
If this doesn't work, you should also look into user permissions for the file that you're trying to access.
I think you should grant the .sh file the executable permission to the OS user used to run the java program by using the below command.
chmod u+x baxter2.sh
For an existing Java code that I want to extend, I need to run a python code from within Java. I am using Process builder for this:
ProcessBuilder pb = new ProcessBuilder("python", "/directorypath/mypython.py");
Process p=pb.start();
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);
}
While the code runs perfectly fine from command line, in Java I get a "We need BeautifulSoup, sorry" error. As far as I understand,this means Java environment is missing some sort of libraries but then the code works perfectly from command line.
Do I need to send some environment variables? If yes, what and how?
I have 'BeautifulSoup4' installed and it is up-to-date.
Not a definitive answer but this looks to me as a problem in the environment which this process runs in; it is probably missing some environment variables which are expected by python to find your "BeautifulSoup4" extension.
A ProcessBuilder has an .environment() method returning a Map<String, String> whose keys are the environment variables and whose values are those variables' values. NOTE THAT MODIFYING THIS MAP ACTUALLY ALTERS THE ENVIRONMENT! (the one of the process you will launch, that is).
Try and print your environment and compare it with what it is when you run from the command line.
I am trying to use Java to find out the versions of Java installed on a machine. I have:
List<String> commands = new ArrayList<String>();
commands.add("java.exe");
commands.add("-version");
ProcessBuilder pb = new ProcessBuilder(commands);
pb.directory(new File("C:\\Program Files\\Java\\jdk1.6.0_45\\bin"));
Process p = pb.start();
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
However, when this is run, the while loop is never executed as the stdInput is empty. If I take out the commands.add("-version"), it will get the input that is output when running "java.exe" command on command line, so it seems adding the -version arguement is causing issues and this also indicates that the directory and java.exe commands are correct. Any help would be appreciated.
The output of java -version is sent to the error stream - reading from that stream should result in the proper output:
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getErrorStream()));
Alternatively, you can call redirectErrorStream(true) to merge the Input and Error streams. If you just wish to just print to the command line, you can use inheritIO on the ProcessBuilder.
The currently running java version can be found without the need for a ProcessBuilder by retrieving the appropriate System property
System.out.println(System.getProperty("java.version"));
java -version prints to stderr. Try using:
ProcessBuilder pb = new ProcessBuilder(commands).redirectErrorStream(true);
That will put stderr in the same stream as stdout and the rest of your code can look as it does now.
Using Java's ProcessBuilder, I can run an external script, and redirect its output into my GUI.
Process proc = pb.start();
BufferedReader bri = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line = "";
while (proc.isAlive())
{
// bri may be empty or incomplete.
while ((line = bri.readLine()) != null)
{
textArea.appendText(line);
}
}
Now, the script I am running also calls other scripts and processes. Two of these, that should be captured, are currently displayed in their own xterm windows. Is it possible to also capture these outputs, and display in a similar manner?.
If these outputs are being managed by your source script, I think it will work. Just as an advice, take a look in this article: When Runtime.exec() won't
It is extremammly important to read it to learn how to work with external processes correctly.
I want to get the path name and arguments of running processes using java code. Is there any solution?
For instance, on Windows, one possibility is to encapsulate the system call to TASKLIST.EXE
Extract from the code:
Process p = Runtime.getRuntime().exec("tasklist.exe /fo csv /nh");
BufferedReader input = new BufferedReader
(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
if (!line.trim().equals("")) {
// keep only the process name
line = line.substring(1);
processes.add(line.substring(0, line.indexOf(""")));
}
}
You should use tasklist /V though, since it comes with the parameters of the processes.
You could use the SIGAR framework, which gives you native support for Linux, FreeBSD, Windows, Solaris, AIX, HP-UX and Mac OSX