I have sendmail file that contains this script echo "sample message" | /usr/bin/swaks --to email#gmail.com I want to run it from java using this code :
ProcessBuilder pb = new ProcessBuilder("sendmail");
Process p = pb.start()
but the email is not sent. Whats wrong and how can i fix this?
edit : running ./sendmail is working, and the email is sent to my mail
I think the problem is that your java application is ending before the script finishes.
Try this:
ProcessBuilder pb = new ProcessBuilder("./sendmail.sh");
Process p = pb.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String readline;
int i = 0;
while ((readline = reader.readLine()) != null) {
System.out.println(++i + " " + readline);
}
The above code should print out what your command prints which could help you debug. It also has the side effect of blocking until the script is finished.
If that works and you don't care about the output, you can do this:
ProcessBuilder pb = new ProcessBuilder("./test.sh");
Process p = pb.start();
p.waitFor();
Related
I am writing a java server process that in addition should run vb.exe file with parameters in windows only.
I tried to use ProcessBuilder with start function and Process with exec function but I have no error but nothing happens!
the cmd for example:
"C:\AL500\BIAFLABEL\AddToQueue.exe" "C:\AL500\BiafLabel\Templates\2.xml" -printer \\mickaelbpc\System-N
the command line definitions in the code:
String fullcmd = "\"C:\\AL500\\BIAFLABEL\\AddToQueue.exe\" \"C:\\AL500\\BiafLabel\\Templates\\2.xml\" -printer \\\\mickaelbpc\\System-N";
String fullcmd1 = "C:\\AL500\\BIAFLABEL\\AddToQueue.exe C:\\AL500\\BiafLabel\\Templates\\2.xml -printer \\\\mickaelbpc\\System-N";
String cmd1 = "C:\\AL500\\BIAFLABEL\\AddToQueue.exe";
String cmd2 = "C:\\AL500\\BiafLabel\\Templates\\2.xml";
String cmd3 = "-printer";
String cmd4 = "\\\\mickaelbpc\\System-N";
String[] command = new String[]{cmd1, cmd2, cmd3,cmd4};
Process + array:
File dir = new File("C:/workspace");
Process process = Runtime.getRuntime().exec(command, null, dir);
process.waitFor();
InputStream stdout = process.getInputStream();
InputStream stderr = process.getErrorStream();
String strData;
StringBuffer sb = new StringBuffer("");
BufferedReader brData = new BufferedReader(new
InputStreamReader(stdout));
while ((strData = brData.readLine()) != null)
{
sb = sb.append(strData).append("\r\n");
}
brData.close();
ProcessBuilder + string command with ":
ProcessBuilder pb=new ProcessBuilder(fullcmd);
pb.redirectErrorStream(true);
Process process1=pb.start();
BufferedReader inStreamReader = new BufferedReader(
new InputStreamReader(process1.getInputStream()));
String line;
while (true) {
line = inStreamReader.readLine();
if (line == null) { break; }
System.out.println(line);
ProcessBuilder + string command with no ":
File log = new File("log");
ProcessBuilder pb=new ProcessBuilder(/*command*/fullcmd1);
pb.redirectErrorStream(true);
pb.redirectOutput(Redirect.appendTo(log));
Process process1=pb.start();
BufferedReader inStreamReader = new BufferedReader(
new InputStreamReader(process1.getInputStream()));
String line;
while (true) {
line = inStreamReader.readLine();
if (line == null) { break; }
System.out.println(line);
}
after the changes I am getting this error: "java.io.IOException: Cannot run program "C:\AL500\BIAFLABEL\AddToQueue.exe C:\AL500\BiafLabel\Templates\2.xml -printer \mickaelbpc\System-N": CreateProcess error=2, The system cannot find the file specified" can you please advise?
ProcessBuilder with cmd.exe:
ProcessBuilder pb=new ProcessBuilder("cmd.exe","/c",fullcmd);
pb.redirectErrorStream(true);
Process process1=pb.start();
BufferedReader inStreamReader = new BufferedReader(
new InputStreamReader(process1.getInputStream()));
String line;
while (true) {
line = inStreamReader.readLine();
if (line == null) { break; }
System.out.println(line);
}
I did all the options and more...if it will be necessary I will add more examples
the vb exe should print a file. any idea how to run it from java process? or what is wrong with my code?
Study the error and output stream of the command. Need to redirect them and stream them in a separate thread. Or try this fronm
File log = new File("log");
pb.redirectErrorStream(true);
pb.redirectOutput(Redirect.appendTo(log));
Is the full path correct? Can you print the commad line space seperated to a file called run.cmd and run that manually and see what happens from prompt?
which directory are you starting the process from might have to be different than the one that your java program is running at? Process builder has a https://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html#directory()
To know which directory your java program is using do this:
File f = new File("./");
try{
System.out.println("Start dir is :" + f.getCanonicalFile());
}catch...
https://docs.oracle.com/javase/7/docs/api/java/io/File.html#getCanonicalFile()
i do not think you do not need to add quotes, just set them in the array with actual values. but if running from a .cmd you will need to qualify params with spaces by putting quotes. best to have no spaces in the paths or params when testing.
See github.com/tgkprog/nli/blob/master/RunCmd.java if ur redirecting to log, dont get the stream again in your loop. and dont call via cmd.exe. in my example ignore the actual commmand, put ur exe and params, i just called a sh file as on ubuntu. You call with your 4 params
Im trying to run python script via terminal but it always throws an exception: No such file or directory
StringBuffer output = new StringBuffer();
String command = "python3 Users/lounah/Documents/programming/ApplicationName/scriptName.py " + params.toString();
ProcessBuilder processBuilder = new ProcessBuilder(command);
Process process = processBuilder.start();
BufferedReader reader =
new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine())!= null) {
output.append(line + "\n");
}
When you pass a string in ProcessBuilder it tries to run a program located in that path.
Instaed you should use a String[] with the path of your executable ( '/python3/python.exe' or 'python' or 'py') followed by the path of your script, followed by the arguments.
String[] command = {
"python3",
"Users/lounah/Documents/programming/ApplicationName/scriptName.py",
params.toString()
};
ProcessBuilder processBuilder = new ProcessBuilder(command);
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.