Running a bash command from within a Java program - java

Consider a piece of Java code:
import java.io.IOException;
public class Demo{
public static void main(String []args) throws IOException{
...
String abc="i am here";
System.out.println(abc);
}
}
I want to run - echo "THIS IS STUFF FOR THE FILE" >> file1.txt - immediately after the System.out.println() line, assuming file1.txt is in the same directory.

The ProcessBuilder class is the more modern version.
import static java.lang.ProcessBuilder.Redirect.appendTo;
ProcessBuilder pb = new ProcessBuilder("/bin/echo", "THIS IS STUFF FOR THE FILE");
pb.redirectOutput(appendTo(new File("file1.txt")));
Process p = pb.start();
Notice that this calls /bin/echo directly instead of having bash look through the PATH. That's safer, as there is no chance of getting a hacked echo. Also, since this doesn't use bash, Java is used to redirect the output.

Use the Runtime.getRuntime().exec() command like so:
Runtime.getRuntime().exec("echo 'THIS IS STUFF FOR THE FILE!' > file1.txt");
The documentation can be read here.
If it's not working or you find the command handy and want to know more about it, do yourself a favour and read this. It will save you sweat.

Related

Unable to run java commands using processbuilder

I am trying to run a java class file from another java program.
This is my program:
import java.io.File;
import java.io.IOException;
import java.lang.ProcessBuilder.Redirect;
public class RunJava {
public static void main(String[] args) throws IOException {
ProcessBuilder pb = new ProcessBuilder("java","HelloWorld");
pb.directory(new File("/home/local/prasanth-8508"));
pb.redirectOutput(Redirect.INHERIT);
pb.redirectError(Redirect.INHERIT);
pb.start();
}
}
After running this program I get the following error:
Exception in thread "main" java.io.IOException: Cannot run program "java"
But when I run any java commands from my terminal, they work absolutely fine.
Another thing I found is, when I run the command: echo $PATH in my terminal and using the ProcessBuilder (ProcessBuilder pb = new ProcessBuilder("bash","-c","echo $PATH");), they are showing different outputs. i.e The path to jdk/bin is not displayed in the ProcessBuilder command.
How can I solve this issue?
Yes, As #MichaelBerry said it is possible that you may not have permission to access it but other then that also I want to include,
Here you have started with very good ProcessBuilder you just need to modify small things like parameter -jar in the constructor of processBuilder.
I've posted below sample code which may help you to understand how it will work.
ProcessBuilder pb = new ProcessBuilder("/path/to/java", "-jar", "your.jar");
pb.directory(new File("preferred/working/directory"));
Process p = pb.start();

How to import another script file in Jshell

I'm looking to use jshell to replace bash for command line processing.
I've created a simple class fs in the file fs.jsh (yes poor naming) that has a number of utility functions like:
// file fs.jsh
class fs
{
static void println(String line)
{
System.out.println(line);
}
}
I know want to include fs.jsh from another file:
e.g.
// helloworld.jsh
import fs.jsh
fs.println("Hello World");
The above code gives the error:
package fs does not exist
| import fs.jsh;
I've also tried:
import fs;
Which gives:
Error:
| '.' expected
| import fs;
So how do I import one script file from another.
One thing that you can make sure is to create an instance of the class before you access its method :
new fs().println("Hello World");
Another, do make sure the sequence in which the scripts are executed is fixed if one relies on the code of the other.
Scripts are run in the order in which they’re entered on the command
line. Command-line scripts are run after startup scripts. To run a
script after JShell is started, use the /open command.
Additionally, an import without a package doesn't make much sense and you cannot have packages in Jshell snippets.
The way you can do it is somewhat like:
Have one script file some.jsh
Another script file sometwo.jsh which calls it
Eventually, open the script sometwo.jsh

Java - Command Execution in Runtime

I tried out a simple program to execute Linux command at run time. But the following program gets compiled and runs without any error, but the text file is not getting created as intended.Is there anything wrong in this program?
import java.io.*;
class ExecuteJava
{
public static void main(String args[])
{
String historycmd = "cat ~/.bash_history >> Documents/history.txt";
try
{
Runtime runtime = Runtime.getRuntime();
Process proc = runtime.exec(historycmd);
}
catch(Exception e)
{
System.out.println(e);
}
}
}
Try accessing some of the functions Process provides. I'd start with exitValue. Typically a -1 indicates something went wrong while a 0 means nothing especially bad happened.
Also try InputStream and Error Stream, and read them fully. See if either has useful feedback for you.
Other than that, try what andy256 suggests in comments. Ensure the Documents directory exists in the executing directory of the program.
The append operator >> is meant to be interpreted as part of the command shell. Use
String[] historycmd =
{ "bash", "-c", "cat ~/.bash_history >> Documents/history.txt"};

running scripts through processbuilder

I'm trying to run Python, Ruby, C, C++, and Java scripts from a java program, and Processbuilder was suggested to me as a good way to run the scripts. From what I understand, Processbuilder mostly runs native files (.exe on windows, etc.). However, I have heard a few things about running scripts (nonnative) files using Processbuilder. Unfortunately, everything I find on the subject is incredibly vague.
If someone could clarify a way to run nonnative scripts such as Python, Ruby, etc. I would be most grateful!
You can check the ProcessBuilder documentation over at Sunoracle, but basically, you can run the interpreter for the scripting language and pass the script you want to run to it.
For example, let's say you have a script in /home/myuser/py_script.py, and python is in /usr/bin/
class ProcessRunner
{
public static void main(String [] args)
{
ProcessBuilder pb = new ProcessBuilder("/usr/bin/python", "/home/myuser/py_script.py");
Process p = pb.start();
}
}
An extremely basic example, you can get fancier with changing the working directory and change the environment.
You can also construct ProcessBuilder with a String array or a subtype of List<String>. The first item in the list should be the program/executable you want to run, and all the following items are arguments to the program.
String pbCommand[] = { "/usr/bin/python", "/home/myuser/py_script.py" };
ProcessBuilder pb = new ProcessBuilder(pbCommand);
Process p = pb.start();
To avoid having to manually enter the entire location of the script, which may also result in portability issues, here's what I did:
String pwd = System.getProperty("user.dir");
ProcessBuilder pb = new ProcessBuilder("/usr/bin/python", pwd+'/'+scriptName, arg1, arg2);
Process p = pb.start();

Running a program from within Java code

What is the simplest way to call a program from with a piece of Java code? (The program I want to run is aiSee and it can be run from command line or from Windows GUI; and I am on Vista but the code will also be run on Linux systems).
Take a look at Process and Runtime classes. Keep in mind that what you are trying to accomplish is probably not platform independent.
Here is a little piece of code that might be helpful:
public class YourClass
{
public static void main(String args[])
throws Exception
{
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("name_of_your_application.exe");
int exitVal = proc.exitValue();
System.out.println("Process exitValue: " + exitVal);
}
}
One question in S.O. discussing similiar issues. Another one. And another one.
You can get a runtime instance using Runtime.getRuntime() and call the runtime's exec method, with the command to execute the program as an argument.
For example:
Runtime runTime = Runtime.getRuntime ();
Process proc = rt.exec("iSee.exe");
You can also capture the output of the program by using getting the InputStream from the process.
The difficulty you will run into is how to get the application to know the path. You may want to use an xml or config file, but if you use this link, it should explain how to run a file:
http://www.javacoffeebreak.com/faq/faq0030.html
You may also want to consider passing in some kind of argument to your program to facilitate finding the specific program you want to run.
This could be with command line arguments, properties files or system properties.

Categories