Executing Fabric Script through JAVA - java

I have this simple fab script and I want to execute this through JAVA:
from __future__ import with_statement
from fabric.api import *
from fabric.contrib.console import confirm
env.hosts = ['localhost']
def updatefile():
with shell_env(TERM='vt100'):
with cd('/Users/'):
run("pwd")
run("ls -l")
def execute():
updatefile()
When I execute this script from command line it works : fab -f test.py executes but I want to execute via java. Tried with ..
public class ExecuteScript {
#Test
public void testExecuteScript() throws NumberFormatException, IOException{
StringBuffer output = new StringBuffer();
Process p;
try {
p = Runtime.getRuntime().exec("fab -f src/test/resources/scripts/test.py execute");
p.waitFor();
BufferedReader reader =
new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine())!= null) {
output.append(line + "\n");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(output.toString());
}
}
It doesn't work.. looked at the documentation for java examples in http://fabric8.io/gitbook/quickstarts.html the links are broken.

Environment, make sure you're using your environment. I would suggest you use virtualenv, looks something like this:
virtualenv .env (dont do this in your src folder, if anything it should be one directory down, and also please don't check this into your source control)
source .env/bin/activate
then install your dependencies:
pip install fabric
?? what ever else you need.
then this is the important part:
./.env/bin/fab -f src/test/resources/scripts/test.py execute

Related

Executing Process in java to call external python program but program does not print anything to console

We can use Jython to implement python in java, but I dont want to go for that approach, what I am looking for is using command line utility and fire python command to execute the code and get the console output in java code.
python Main.py < input.txt
I used above command in terminal, it works there, giving me output, but unable to get the output in java code.
Note: Main.py and input.txt and java code in the same folder
What I am doing wrong in java code?
Here is Sample java code which I am calling in order to execute external python code
try {
Process process = Runtime.getRuntime()
.exec("python Main.py < input.txt");
process.waitFor();
System.out.println(process);
StringBuilder output
= new StringBuilder();
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
}
System.out.println("here");
int exitVal = process.waitFor();
if (exitVal == 0) {
System.out.println("Success!");
System.out.println(output);
} else {
System.out.println("Process failed");
}
} catch (Exception e) {
// TODO: handle exception
System.out.println(e);
}
Here is a sample python code:
x = input();
y = input();
print(type(x));
print(type(y));
print(x + y);
here is a sample input file which I am passing as a input to the python code
30
40
As sandip showed, executing a command in java is not the same as running commands through BASH.
At first I tried to execute
bash -c "python Main.py < input.txt" (through java).
For some reason this didn't work, and even if it did its not a great solution as its dependent on the system its running on.
The solution I found to work was by using ProcessBuilder to first make the command, and redirect its input to a file. This allows you to keep the python code unchanged, and for me at least, give the same result as just running the BASH command.
Example:
ProcessBuilder pb = new ProcessBuilder("python3","Main.py");
//Make sure to split up the command and the arguments, this includes options
//I only have python3 on my system, but that shouldn't affect anything
pb.redirectInput(new File("./input.txt"));
System.out.println(pb.command());
Process process = pb.start();
//The rest is the exact same as the code in the question
Heres the ProcessBuilder docs for quick reference
java process not accept < symbol to input file in python command.
Instead you can run like this
python file
f = open("input.txt", "r")
for x in f:
print(type(x));
print(x)
java file
Process process = Runtime.getRuntime().exec("python Main.py input.txt");
process.waitFor();
System.out.println(process);
StringBuilder output
= new StringBuilder();
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
}
System.out.println("here");
int exitVal = process.waitFor();
if (exitVal == 0) {
System.out.println("Success!");
System.out.println(output);
} else {
System.out.println("Process failed");
}
} catch (Exception e) {
// TODO: handle exception
System.out.println(e);
}
and use and same text file.
It should print in console

Java program to run shell commands from a windows machine

I am trying to run a Java program to shell out commands on a remote (Linux) machine. I can get the putty.exe to run and then connect to the machine using SSH keys. But am not able to run the actual commands such as "bash" "ps-ef" or "ls -la". Currently using the Java runtime.exec, not sure if using the java.lang.ProcessBuilder would help? What am I doing wrong ? Any help/guidance would be greatly appreciated.. Thanks in advance
package hello;
import java.io.*;
public class RuntimeExample {
public static void main(String args[]) throws IOException {
try{
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec(new String[]{"C:\\Users\\yky90455\\Desktop\\putty.exe","abc#login.testserver.helloworld.co.uk","bash", "ps -ef"});
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
System.out.printf("Output of running the command is:");
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
try Jsch From here to get the shell scrips executed from Java to some remote Linux machine. I have worked on this and it was really fun.although you may find little shortage of docs for understanding this but you can overcome that easily.
Also consider ExpectJ which is a wrapper around TCL Expect. The project does not appear to have any active development since mid 2010, but I have used it for SSH in the past.
http://expectj.sourceforge.net/apidocs/expectj/SshSpawn.html
Thanks for all your answers. I tried Ganymed SSH-2 library. It works well for the basic commands on the remote machine. I will have to explore other APIs in case I run into any limitation with SSH-2.
public class triggerPutty {
public static void main(String[] a) {
try {
String command = "putty.exe user#abc.text.com -pw password -m C:\\containing_comman.txt";
Runtime r = Runtime.getRuntime();
Process p = null;
p = r.exec(command);
p.waitFor();
p.destroy();
} catch (Exception e) {
e.printStackTrace();
}
}
}
-m helps to run your command from that file.
You can keep N number of commands in that file.. ## Heading ##

how to launch a shell script in a new gnome terminal, from a java program

I'm trying to run a shell script (say myscript.sh) from a java program.
when i run the script from terminal, like this :
./myscript.sh
it works fine.
But when i call it from the java program, with the following code :
try
{
ProcessBuilder pb = new ProcessBuilder("/bin/bash","./myScript.sh",someParam);
pb.environment().put("PATH", "OtherPath");
Process p = pb.start();
InputStreamReader isr = new InputStreamReader(p.getInputStream());
BufferedReader br = new BufferedReader(isr);
String line ;
while((line = br.readLine()) != null)
System.out.println(line);
int exitVal = p.waitFor();
}catch(Exception e)
{ e.printStackTrace(); }
}
It doesnt goes the same way.
Several shell commands (like sed, awk and similar commands) get skipped and donot give any output at all.
Question : Is there some way to launch this script in a new terminal using java.
PS : i've found that "gnome-terminal" command launches a new terminal in shell,
But, i'm unable to figure out, how to use the same in a java code.
i'm quite new to using shell scripting. Please help
Thanks in advance
In java:
import java.lang.Runtime;
class CLI {
public static void main(String args[]) {
String command[] = {"/bin/sh", "-c",
"gnome-terminal --execute ./myscript.sh"};
Runtime rt = Runtime.getRuntime();
try {
rt.exec(command);
} catch(Exception ex) {
// handle ex
}
}
}
And the contents of the script are:
#!/bin/bash
echo 'hello!'
bash
Notes:
You'll do this in a background thread or a worker
The last command, in the shell script, is bash; otherwise execution completes and the terminal is closed.
The shell script is located in the same path as the calling Java class.
Don't overrwrite your entire PATH...
pb.environment().put("PATH", "OtherPath"); // This drops the existing PATH... ouch.
Try this instead
pb.environment().put("PATH", "OtherPath:" + pb.environment().get("PATH"));
Or, use the full directories to your commands in your script file.
You must set your shell script file as executable first and then add the below code,
shellScriptFile.setExecutable(true);
//Running sh file
Process exec = Runtime.getRuntime().exec(PATH_OF_PARENT_FOLDER_OF_SHELL_SCRIPT_FILE+File.separator+shellScriptFile.getName());
byte []buf = new byte[300];
InputStream errorStream = exec.getErrorStream();
errorStream.read(buf);
logger.debug(new String(buf));
int waitFor = exec.waitFor();
if(waitFor==0) {
System.out.println("Shell script executed properly");
}
This worked for me on Ubuntu and Java 8
Process pr =new ProcessBuilder("gnome-terminal", "-e",
"./progrm").directory(new File("/directory/for/the/program/to/be/executed/from")).start();
The previous code creates a new terminal in a specificied directory and executes a command
script.sh Must have executable permissions
public class ShellFileInNewTerminalFromJava {
public static void main(String[] arg) {
try{
Process pr =new ProcessBuilder("gnome-terminal", "-e", "pathToScript/script.sh").start();
}catch(Exception e){
e.printStackTrace();
}
}
}

Run monkey from java

I have this script in file script.txt
And I run this like this
monkeyrunner /home/user/script.txt
this is my script.txt
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
import time
device = MonkeyRunner.waitForConnection("wait forever","emulator-5554")
package = 'com.pak.pak1'
activity = 'com.pak.pak1.MyActivity'
runComponent = package + '/' + activity
# Runs the component
device.startActivity(component=runComponent)
time.sleep(1)
The thing I want to do is to run the script from java
This code runs a shell command for example to srart the script
try {
new Thread() {
public void run() {
Process p;
try {
p = Runtime.getRuntime().exec("monkeyrunner /home/user/script.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
p.waitFor();
} catch (Exception e) {
//e.printStackTrace();
}
}
}.start();
} catch (Exception ie) {
}
And finally mu question is how can I directly from java run the monkey runner commands, I do not want to have the script.txt file. Is this possible ? My goal is to run the monkey runner but I do not want to have the script.txt file
Apparently, if you include the MonkeyRunner chimpchat.jar (and it's jar depedencies) on your classpath, then you can call the monkey runner Java classes directly inside your Java application. Check out this class and this class that make up an example:
Another thread on this subject
This looks awfully complicated, but still..
monkeyrunner can run interactively, so write directly to stdin (get it from p.getOutputStream()) all strings you want it to run.
you might need to exhaust the stdout before issuing any command, but I don't think that will be the case.

using Runtime.exec() in Java

What do you have to do in Java to get the Runtime.exec() to run a program that is on the path? I'm trying to run gpsbabel which I have put into the path (/usr/local/bin).
public class GpxLib {
public static void main(String[] args) {
try
{
Runtime r = Runtime.getRuntime();
Process p = r.exec("gpsbabel -i garmin -f usb: -o gpx -F -");
InputStream is = p.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
while (true)
{
String s = br.readLine();
if (s == null)
break;
System.out.println(s);
}
br.readLine();
} catch (IOException e) {
e.printStackTrace(System.err);
}
}
}
I added a call to System.out.println(System.getenv("PATH")); which only prints out
/usr/bin:/bin:/usr/sbin:/sbin
so for some reason /usr/local/bin doesn't show up. Looks like this is a MacOSX question or an Eclipse question, not a Java question. edit: asked this question on superuser instead.
It will inherit the path from the Java process. So whatever environment the Java process has, the spawned process will have as well. Here's how to check the environment:
Map<String, String> env = System.getenv();
for (String envName : env.keySet()) {
System.out.format("%s=%s%n", envName, env.get(envName));
}
Have you set the PATH and exported it ? If you don't export it, then it's not available to subprocesses.
Additionally, you must consume stdout and stderr concurrently, to prevent blocking. Otherwise stuff will work in some circumstances, then your spawned process will output a different quantity of data and everything will grind to a halt.
See this answer for more details.
Here is the solution:
ProcessBuilder proc = new ProcessBuilder("<Directory PAth>" + "Executable.exe");
proc.redirectOutput(ProcessBuilder.Redirect.INHERIT);
proc.directory(fi); //fi = the output directory path
proc.start();
is the path where program\application's excutable is located e.g "C:\MyProg\"

Categories