Calling python script from Java using runtime.getruntime.exec - java

I have a java web development project, and want to call a python script to run in the background and then carry on with the java.
String command = "cmd.exe /c cd "C:\\path\\to\\py\\" && python script.py";
Process p = Runtime.getRuntime().exec(command);
Nothing seems to happen when i call this, but i need to change directory first as the script accesses files in its directory.
Thanks for your help
Edit:
Correct answer was adding start, this is my edited code
String command = "cmd.exe /c cd "C:\\path\\to\\py\\" && start python script.py";
Process p = Runtime.getRuntime().exec(command);

Rather than using cmd to change the directory, you can set a process's working directory from the Java side. For example
ProcessBuilder pb = new ProcessBuilder("python", "script.py");
pb.directory(new File("C:\\path\\to\\py"));
Process p = pb.start();

Did you configure your environment to support "executable" python scripts?
If not, you should call it like this:
String command = "cmd.exe /c start python path\to\script\script.py";
Process p = Runtime.getRuntime().exec(command);
The start command runs the appropriate executable (in this case python interpreter), with its supplied arguments (in this case the script itself).

Related

Can't save mysql dump file to my hard drive from a java progam [duplicate]

Process p = Runtime.getRuntime().exec("sh somescript.sh &> out.txt");
I am running this command using Java. The script is running but it's not redirecting its stream to the file. Moreover, the file out.txt is not getting created.
This script runs fine if I run it on shell.
Any ideas?
You need to use ProcessBuilder to redirect.
ProcessBuilder builder = new ProcessBuilder("sh", "somescript.sh");
builder.redirectOutput(new File("out.txt"));
builder.redirectError(new File("out.txt"));
Process p = builder.start(); // may throw IOException
When you run a command, there is no shell running and any shell commands or functions are not available. To use something like &> you need a shell. You have one but you are not passing it to it. try instead.
Runtime.getRuntime().exec(new String[] { "sh", "somescript.sh &> out.txt" });

Java, ProcessBuilder for python script with python module (numpy)

I want to use ProcessBuilder to execute a python script. I can execute this script with the command "python3 myscript.py" without any problem. But When I use ProcessBuilder in java, I get an error from my script :
import numpyImportError: No module named 'numpy'
numpy is the module that I want to use, but I can't find it.
This is the way I call my script :
ProcessBuilder builder = new ProcessBuilder("python3","main.py","-rd ",selectedFile.getAbsolutePath());
builder.redirectErrorStream(true);
Process process = builder.start();
You need to specify your python path:
run in your terminal: "which python3"
ProcessBuilder builder = new ProcessBuilder("your/python/path/python3","main.py","-rd ",selectedFile.getAbsolutePath());

save the output of command prompt to a file [duplicate]

Process p = Runtime.getRuntime().exec("sh somescript.sh &> out.txt");
I am running this command using Java. The script is running but it's not redirecting its stream to the file. Moreover, the file out.txt is not getting created.
This script runs fine if I run it on shell.
Any ideas?
You need to use ProcessBuilder to redirect.
ProcessBuilder builder = new ProcessBuilder("sh", "somescript.sh");
builder.redirectOutput(new File("out.txt"));
builder.redirectError(new File("out.txt"));
Process p = builder.start(); // may throw IOException
When you run a command, there is no shell running and any shell commands or functions are not available. To use something like &> you need a shell. You have one but you are not passing it to it. try instead.
Runtime.getRuntime().exec(new String[] { "sh", "somescript.sh &> out.txt" });

How to run Java command through code?

I am trying to execute the below code
String command="cmd /c ls";
String location="C:\\project";
final Process process = Runtime.getRuntime().exec(
dosCommand + " " + location);
I am getting the files, but when I run the cmd /c java I didn't get the output.
my Java home is added to environment variables.
When I give Java in command prompt I am getting the Java related files. I am not getting through my program.
I assume you want to run a Java program throught command line in your Java program? Try this:
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec("java ...");
http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html
Assuming you use Java 1.5 or higher, I'd recommend using ProcessBuilder if you want to execute from a different path. It allows you to easily set the working directory for the process.
final Process pr = new ProcessBuilder(
"java",
"-Xms512M",
"-Xmx1024M",
"-jar",
"your_jar_to_use.jar",
"your Java class")
.directory(new File("<your directory>")) //Set the working directory to <your directory>
.start();
Or better yet, use the Java Compiler API, as demonstrated in this article and this one.

How to execute unix commands through Windows/cygwin using Java

I am trying to accomplish two things:
I am running cygwin on Windows7 to execute my unix shell commands and I need to automate the process by writing a Java app. I already know how to use the windows shell through Java using the 'Process class' and Runtime.getRuntime().exec("cmd /c dir"). I need to be able to do the same with unix commands: i.e.: ls -la and so forth. What should I look into?
Is there a way to remember a shell's state?
explanation: when I use: Runtime.getRuntime().exec("cmd /c dir"), I always get a listing of my home directory. If I do Runtime.getRuntime().exec("cmd /c cd <some-folder>") and then do Runtime.getRuntime().exec("cmd /c dir") again, I will still get the listing of my home folder. Is there a way to tell the process to remember its state, like a regular shell would?
It seems that the bash command line proposed by PaĆ­lo does not work:
C:\cygwin\bin>bash -c ls -la
-la: ls: command not found
I am having trouble figuring out the technicalities.
This is my code:
p = Runtime.getRuntime().exec("C:\\cygwin\\bin\\bash.exe -c ls -la");
reader2 = new BufferedReader(new InputStreamReader(p.getInputStream()));
line = reader2.readLine();
line ends up having a null value.
I added this to my .bash_profile:
#BASH
export BASH_HOME=/cygdrive/c/cygwin
export PATH=$BASH_HOME/bin:$PATH
I added the following as well:
System Properties -> advanced -> Environment variables -> user variebales -> variable: BASH, value: c:\cygwin\bin
Still nothing...
However, if I execute this instead, it works!
p = Runtime.getRuntime().exec("c:\\cygwin\\bin\\ls -la ~/\"Eclipse_Workspace/RenameScript/files copy\"");
1. Calling unix commands:
You simply need to call your unix shell (e.g. the bash delivered with cygwin) instead of cmd.
bash -c "ls -la"
should do. Of course, if your command is an external program, you could simply call it directly:
ls -la
When starting this from Java, it is best to use the variant which takes a string array, as then
you don't have Java let it parse to see where the arguments start and stop:
Process p =
Runtime.getRuntime().exec(new String[]{"C:\\cygwin\\bin\\bash.exe",
"-c", "ls -la"},
new String[]{"PATH=/cygdrive/c/cygwin/bin"});
The error message in your example (ls: command not found) seems to show that your bash can't find the ls command. Maybe you need to put it into the PATH variable (see above for a way to do this from Java).
Maybe instead of /cygdrive/c/cygwin/bin, the right directory name would be /usr/bin.
(Everything is a bit complicated here by having to bridge between Unix and Windows
conventions everywhere.)
The simple ls command can be called like this:
Process p = Runtime.getRuntime().exec(new String[]{"C:\\cygwin\\bin\\ls.exe", "-la"});
2. Invoking multiple commands:
There are basically two ways of invoking multiple commands in one shell:
passing them all at once to the shell; or
passing them interactively to the shell.
For the first way, simply give multiple commands as argument to the -c option, separated by ; or \n (a newline), like this:
bash -c "cd /bin/ ; ls -la"
or from Java (adapting the example above):
Process p =
Runtime.getRuntime().exec(new String[]{"C:\\cygwin\\bin\\bash.exe",
"-c", "cd /bin/; ls -la"},
new String[]{"PATH=/cygdrive/c/cygwin/bin"});
Here the shell will parse the command line as, and execute it as a script. If it contains multiple commands, they will all be executed, if the shell does not somehow exit before for some reason (like an exit command). (I'm not sure if the Windows cmd does work in a similar way. Please test and report.)
Instead of passing the bash (or cmd or whatever shell you are using) the commands on the
command line, you can pass them via the Process' input stream.
A shell started in "input mode" (e.g. one which got neither the -c option nor a shell script file argument) will read input from the stream, and interpret the first line as a command (or several ones).
Then it will execute this command. The command itself might read more input from the stream, if it wants.
Then the shell will read the next line, interpret it as a command, and execute.
(In some cases the shell has to read more than one line, for example for long strings or composed commands like if or loops.)
This will go on until either the end of the stream (e.g. stream.close() at your side) or executing an explicit exit command (or some other reasons to exit).
Here would be an example for this:
Process p = Runtime.getRuntime().exec(new String[]{"C:\\cygwin\\bin\\bash.exe", "-s"});
InputStream outStream = p.getInputStream(); // normal output of the shell
InputStream errStream = p.getInputStream(); // error output of the shell
// TODO: start separate threads to read these streams
PrintStream ps = new PrintStream(p.getOutputStream());
ps.println("cd /bin/");
ps.println("ls -la");
ps.println("exit");
ps.close();
You do not need cygwin here. There are several pure Java libraries implementing SSH protocol. Use them. BTW they will solve your second problem. You will open session and execute command withing the same session, so the shell state will be preserved automatically.
One example would be JSch.

Categories