I used to write PHP code to execute pig command, it worked well,
Now I switch to Java but seems it won't work, here is my code:
String pigCommand = "pig -x local -p ouput=/tmp my_pig_script.pig";
Runtime r = Runtime.getRuntime();
Process p;
int exitVal;
try {
p = r.exec(pigCommand);
exitVal = p.waitFor();
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
System.out.println("exitVal: " + exitVal);
System.out.println("Done");
If I run the that pig command in console directly, it works, if I replace
that Pig command with other shell command say 'ping www.yahoo.com', and run the
java Program, it works too. So what might be the problem? thanks
You should use PigServer to execute pig scripts from java programs. It is more foolproof and more portable.
Also see this answer: https://stackoverflow.com/a/11299259/373151
Related
I'm trying to send docker commands using Java Runtime.
Commands like docker cp works very nice with the below method as well as typing directly from the terminal.
First problem is that the docker exec command works only from the terminal, not with the Java Runtime. Other docker commands like docker cp works as expected. The only problem is that I can't run commands on the container, like echoing on the container's terminal.
Also the 2nd problem is that the System.out.println(...)method in the below method, doesn't actually print anything.
private static void runCommand() throws IOException, InterruptedException {
Process proc = Runtime.getRuntime().exec(
new String[]{"/bin/sh",
"-c",
"docker exec -u 0 -it <CONTAINER_NAME> echo", "'abc'"});
BufferedReader reader =
new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line = "";
while ((line = reader.readLine()) != null) {
System.out.print(line + "\n");
}
proc.waitFor();
}
There is no need to run docker inside a shell. You can start the process directly.
As of Java 1.7 you can also use ProcessBuilder.inheritIO() to redirect the standard I/O of the subprocess
Below a working example that prints the output of the echo command:
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command("docker", "exec" , "-it", "<CONTAINER_NAME_OR_ID>", "echo", "abc").inheritIO();
try {
Process process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
int exitCode = process.waitFor();
System.out.println("\nExited with error code : " + exitCode);
} catch (Exception e) {
e.printStackTrace();
}
Hope this helps.
I'm trying to run a shell script from Java (using Runtime.getRuntime().exec(cmd)). All commands in the script file seem to be running normally except the angular-cli (ng) commands.
My Java File:
System.out.println("Executing Script...");
final String[] cmd = new String[]{"/bin/bash", "test.sh"};
final Process process = Runtime.getRuntime().exec(cmd);
process.waitFor();
final BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String s;
while ((s = reader.readLine()) != null) {
System.out.println("Script output: " + s);
}
process.destroy();
System.out.println("Script Executed.");
test.sh:
#!/bin/bash
cd ~/ &&
ng new newAngularProject &&
Outout:
Executing Script...
Script Executed.
No errors are thrown. All other commands work but for some reason, I'm unable to run ng commands. Also, I've tested the file w/o running it from Java - When I run the same script directly on the console, it works perfectly and all commands (including ng commands) work neatly. I'm running on MacOS in case you wanted to know.
Also print the error stream. You will get the error message, if it is there.
final BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
while ((s = errorReader.readLine()) != null) {
System.out.println("error: " + s);
}
Also you can try to use absolute path of ng in your test.sh e.g. /home/my/install/node-vxxx/ng, since the process spawn by java to run your command might not get the environment variable you set in your .bashrc /.bash_aliases
I can execute Linux commands like ls or pwd from Java without problems but couldn't get a Python script executed.
This is my code:
Process p;
try{
System.out.println("SEND");
String cmd = "/bash/bin -c echo password| python script.py '" + packet.toString() + "'";
//System.out.println(cmd);
p = Runtime.getRuntime().exec(cmd);
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String s = br.readLine();
System.out.println(s);
System.out.println("Sent");
p.waitFor();
p.destroy();
} catch (Exception e) {}
Nothing happened. It reached SEND but it just stopped after it...
I am trying to execute a script which needs root permissions because it uses serial port. Also, I have to pass a string with some parameters (packet).
You cannot use the PIPE inside the Runtime.getRuntime().exec() as you do in your example. PIPE is part of the shell.
You could do either
Put your command to a shell script and execute that shell script with .exec() or
You can do something similar to the following
String[] cmd = {
"/bin/bash",
"-c",
"echo password | python script.py '" + packet.toString() + "'"
};
Runtime.getRuntime().exec(cmd);
#Alper's answer should work. Better yet, though, don't use a shell script and redirection at all. You can write the password directly to the process' stdin using the (confusingly named) Process.getOutputStream().
Process p = Runtime.exec(
new String[]{"python", "script.py", packet.toString()});
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(p.getOutputStream()));
writer.write("password");
writer.newLine();
writer.close();
You would do worse than to try embedding jython and executing your script. A simple example should help:
ScriptEngine engine = new ScriptEngineManager().getEngineByName("python");
// Using the eval() method on the engine causes a direct
// interpretataion and execution of the code string passed into it
engine.eval("import sys");
engine.eval("print sys");
If you need further help, leave a comment. This does not create an additional process.
First, open terminal and type "which python3". You will get the complete path of python3. For example "/usr/local/bin/python3"
String[] cmd = {"/usr/local/bin/python3", "arg1", "arg2"};
Process p = Runtime.getRuntime().exec(cmd);
p.waitFor();
String line = "", output = "";
StringBuilder sb = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = br.readLine())!= null) {sb = sb.append(line).append("\n"); }
output = sb.toString();
System.out.println(output);
I can execute Linux commands like ls or pwd from Java without problems but couldn't get a Python script executed.
This is my code:
Process p;
try{
System.out.println("SEND");
String cmd = "/bash/bin -c echo password| python script.py '" + packet.toString() + "'";
//System.out.println(cmd);
p = Runtime.getRuntime().exec(cmd);
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String s = br.readLine();
System.out.println(s);
System.out.println("Sent");
p.waitFor();
p.destroy();
} catch (Exception e) {}
Nothing happened. It reached SEND but it just stopped after it...
I am trying to execute a script which needs root permissions because it uses serial port. Also, I have to pass a string with some parameters (packet).
You cannot use the PIPE inside the Runtime.getRuntime().exec() as you do in your example. PIPE is part of the shell.
You could do either
Put your command to a shell script and execute that shell script with .exec() or
You can do something similar to the following
String[] cmd = {
"/bin/bash",
"-c",
"echo password | python script.py '" + packet.toString() + "'"
};
Runtime.getRuntime().exec(cmd);
#Alper's answer should work. Better yet, though, don't use a shell script and redirection at all. You can write the password directly to the process' stdin using the (confusingly named) Process.getOutputStream().
Process p = Runtime.exec(
new String[]{"python", "script.py", packet.toString()});
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(p.getOutputStream()));
writer.write("password");
writer.newLine();
writer.close();
You would do worse than to try embedding jython and executing your script. A simple example should help:
ScriptEngine engine = new ScriptEngineManager().getEngineByName("python");
// Using the eval() method on the engine causes a direct
// interpretataion and execution of the code string passed into it
engine.eval("import sys");
engine.eval("print sys");
If you need further help, leave a comment. This does not create an additional process.
First, open terminal and type "which python3". You will get the complete path of python3. For example "/usr/local/bin/python3"
String[] cmd = {"/usr/local/bin/python3", "arg1", "arg2"};
Process p = Runtime.getRuntime().exec(cmd);
p.waitFor();
String line = "", output = "";
StringBuilder sb = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = br.readLine())!= null) {sb = sb.append(line).append("\n"); }
output = sb.toString();
System.out.println(output);
I'm trying to run a python script during the execution of my java code, because it will depend on the output received from the python script. So far I've tried using jythonc, unfortunately to no success, and now im trying to use the java Runtime and java Process to execute the python script.
Now I've run into a problem when trying to call the python script. I feel as though it doesn't even call the script because it takes less than a couple seconds to get to the next page....
Could the problem be how I am calling the python script?? I am trying to run this through a web application...
Here is some of my code:
String run = "cmd /c python duplicatetestingoriginal.py" ;
boolean isCreated = fwr.writeFile(BugFile, GD, 500, true, 5, "LET");
if(isCreated){
try{
r = Runtime.getRuntime();
p = r.exec(run);
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
String line = "";
while ((line = stdInput.readLine()) != null) {
System.out.println(line);
}
while ((line = stdError.readLine()) != null) {
errorW.write(line);
}
int exitVal = p.waitFor();
arrayList = fwr.readResults();
}catch(Exception e){
}
}
else{
// troubleshoot....
}
Instead of String for the command, split it to chunks and make a String[]. No need to state cmd /c, I think.
This is a sample code from my application:
//Running on windows
command = new String[4];
command[0]=directory.getCanonicalPath()+"/data/ExtenalApp.exe"; //extenal commandline app, not placed in path, but in subfolder
command[1]=directory.getCanonicalPath()+"/data/SomeFile.txt"; //file needed for the external app, sent as an argument
command[2]=arg1; //argument for the app
command[3]=arg2; //argument for the app
//Running on Mac
command = new String[6];
command[0]="python";
command[1]=directory.getCanonicalPath()+"/data/wp.py"; //path to the script
command[2]="-F"; //argument/Flag/option
command[3]="--dir="+path; //argument/option
command[4]="--filename="+filename; //argument/option
command[5]=argument; //argument/option
Process process = Runtime.getRuntime().exec(command);
process.waitFor();
process.destroy();
I don't handle the Input/Output streams because the script/app doesn't require input, and outputs only when finished, nothing important. Which might not be the case for you.