I am sending some greek text ("αλεξ") to my python program and I expect to get a popup window showing "αλεξ" but instead I get "αλεξ". Then I print the text parsed in and get it back to my java program, the result is "αλεξ" again! I am assuming the problem is the charset on my python program but I read somewhere that python3 uses by default utf-8.
Here is my Java Program :
public void run() {
try {
Runtime rt = Runtime.getRuntime();
String commands = "python -u C:\\Users\\Alex\\Desktop\\PythonProjects\\inputOutput.py";
Process proc = rt.exec(commands);
// read from terminal of the program
BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream(),Charset.forName("UTF-8")));
// write on the terminal of the program
BufferedWriter out = new BufferedWriter(s=new OutputStreamWriter(proc.getOutputStream(), "UTF-8"));
System.out.println(s.getEncoding());
boolean telegramStarted = false;
String s;
while ((s=in.readLine())!=null) {
System.out.println(s);
if (telegramStarted |s.equals("started")) {
out.write("αλεξ");
out.newLine();
out.flush();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
Here is the Python Script :
import ctypes
print('started')
while True :
name = input('Enter your name: ')
ctypes.windll.user32.MessageBoxW(0, name, "Greetings", 1)
print('Hello', name, '!')
Related
I want to print the std ouput of the following Python script using Java Runtime. My ideal result would simply print out "Hello World". Why am I getting java.io.IOException: Cannot run program "python": CreateProcess error=2, The system cannot find the file specified at java.lang.ProcessBuilder.start? My Path and Python environment variables are properly configured.
String commandline = "python /c start python C:\\Users\\Name\\HelloWorld.py"
try {
//TODO java.io.IOException: Cannot run program "dir"
Process process = Runtime.getRuntime().exec(commandline);
process.waitFor();
// Store command line output
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
StringBuilder builder = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
builder.append(line);
builder.append(System.getProperty("line.separator"));
}
String result = builder.toString();
if (result != null) {
PrintWriter out = resp.getWriter();
out.println("<div>" + result + "</div>");
System.exit(0);
} else {
PrintWriter out = null;
}
} catch (IOException e1) {
PrintWriter out = resp.getWriter();
e1.printStackTrace(out);
} catch (InterruptedException e2) {
PrintWriter out = resp.getWriter();
e2.printStackTrace(out);
}
One way to do this would be to change your python output to output to a file. I believe that you can do this somewhat simply by changing the process string to:
String commandline = "python /c start python C:\\Users\\Name\\HelloWorld.py > output.txt"
Then use any of the million ways that java has to open / read files to handle the file, which should contain the output from your python program. You may want to add a thread.sleep(1000) since your python script won't be running in the JVM and may need time to complete, since the instructions in your java program are synchronous.
I have a problem when using while-loops to read the text a command returns.
I have the following code:
class CommandExecuter {
ProcessBuilder builder = null;
Process p = null;
BufferedWriter writer = null;
String str = "";
BufferedReader hey = null;
StringBuffer buffer = null;
CommandExecuter() {
}
public void run() {
builder = new ProcessBuilder("/bin/bash");
try {
p = builder.start();
}
catch (IOException e) {
e.printStackTrace();
}
writer = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
hey = new BufferedReader(new InputStreamReader(p.getInputStream()));
buffer = new StringBuffer();
}
String exec(String command) {
try {
writer.write(command);
writer.newLine();
writer.flush();
int a = 0;
while ((str = hey.readLine()) != null) {
a++;
System.out.println(a);
buffer = buffer.append(str + ":");
}
System.out.println("finished");
return buffer.toString();
}
catch (Exception e) {
e.printStackTrace();
}
return "1";
}
}
The problem is, the while loop is doesn't when the console finished printing text. It never reaches the part where it prints "finished". When using the command ls, it return a 8 lines long String. The variable "a" prints till it reaches 8, and stops, but the loop does not exit because it never reaches the finished part.
You are running an interactive shell and feeding it commands through standard input; once a command is executed, the shell will print its output and keep running, waiting for more commands. Therefore, standard output of the shell process will never be closed.
What you should probably do instead is run each command as its own, new, process, possibly as /bin/bash -c command.
Am calling a p = Runtime.getRuntime().exec(command) on Java 1.8.
The command calls a bash script as follows:
#!/bin/bash
args=("$#")
cat /home/user/Downloads/bigtext.txt | grep ${args[0]}
The above bash script works fine when called with the command line. When called within my Java application using exec() I get no CAT output back. it does not seem to get past p.waitFor(); Where am I going wrong?
If I run a command directly such as "ls -alF" every thing works as expected.
$ java -version java version "1.8.0_31" Java(TM) SE Runtime Environment (build 1.8.0_31-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode)
String tmp = "/home/user/search "+input;
System.out.println(tmp); // /home/user/search sometextarg
String woa = executeCommand(tmp);
private String executeCommand(String command) {
StringBuilder output = new StringBuilder();
BufferedReader reader = null;
Process p;
try {
p = Runtime.getRuntime().exec(command);
p.waitFor();
reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine())!= null) {
output.append(line + "\n");
}
} catch (Exception e) {
e.printStackTrace();
}
return output.toString();
}
Your Java process and your script are deadlocked waiting on each other: you are waiting for the process to exit, the process is waiting for you to read the output.
It happens to work for ls -alF and other commands with small outputs because they all fit in the pipe's buffer (64kib on my system).
Just move the p.waitFor() below the while loop, and you'll have more luck:
private String executeCommand(String command) {
StringBuilder output = new StringBuilder();
BufferedReader reader = null;
Process p;
try {
p = Runtime.getRuntime().exec(command);
reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine())!= null) {
output.append(line + "\n");
}
p.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
return output.toString();
}
If you additionally want this to work correctly with values containing spaces and certain other characters, you have to:
Quote "${args[0]}" in your script.
Rewrite your executeCommand to use Runtime.exec(String[]) instead of Runtime.exec(String).
I am writing a java program that takes command and run it in unix shell. I have managed to get the output, but I need the program to detect if the given command is invalid, now, if I put in an invalid command, it gives me an error. Otherwise, it's working fine. Can anybody help me with this?? Here is my code:
public class TestCommand {
public static void main(String[] args) {
TestCommand obj = new TestCommand();
String sentence ="";
Scanner scn = new Scanner(System.in);
while (sentence != " ")
{
if (sentence !="exit")
{
System.out.println("> ");
sentence = scn.nextLine();
String outPut = obj.executeCommand(sentence);
System.out.println(outPut + "\n");
}
else
{
System.exit(2);
}
}
}
private String executeCommand(String sentence)
{
StringBuffer output = new StringBuffer();
Process p;
try
{
p = Runtime.getRuntime().exec(sentence);
p.waitFor();
BufferedReader bfrd = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = bfrd.readLine())!= null)
{
output.append(line);
}
bfrd.close();
}
catch (Exception e) {
e.printStackTrace();
}
return output.toString();
}
}
Unix shell language is extraordinarily complex. Re-implementing enough of it in java to test for correctness would be a large undertaking. If you just want to find out if some shell code is syntactically correct, you can use bash with the -n option:
bash -n file_with_code_to_test
Or:
bash -n -c string_with_code_to_test
The key thing here is the -n option. It tells bash to read the commands and check their syntax without executing them. Thus, this is safe to run.
You can run these command from java just as you would other bash commands.
bash will return an exit code of 0 if the code is syntactically correct. If it isn't, it will print error messages and return an exit code of 1.
Just to be clear, this checks syntax. It will, for example, not test for the existence of needed files or commands, only that the code is would run if they did exist.
Is there a way to get an output from a shell script program into a variable in Java program(not into the output file). The output of my shell script is the database query execution time and I need to assign that time value to a Java variable. (I am calling that shell script from Java program). And then I will need to do some other calculations on those values in Java.
Update to old question
Since Java 7 there is a new class which can easily deal with OS procecces: ProcessBuilder
.Let's assume we need to store the output of ip_conf.bat into a java String. Contents of c:\tmp\ip_conf.bat
#echo off
REM will go to standard output
ipconfig
REM will go to stadnard error
hey there!
You can read the input streams connected to the standard and error outputs of the subprocess:
ProcessBuilder pb = new ProcessBuilder("C:\\tmp\\ip_conf.bat");
Process p = pb.start();
String pOut = "";
try (InputStream stdOut = p.getInputStream();
BufferedInputStream bufferedStdOut = new BufferedInputStream(stdOut);
ByteArrayOutputStream result = new ByteArrayOutputStream()) {
int bytes = 0;
while ((bytes = bufferedStdOut.read()) != -1) {
result.write(bytes);
}
pOut = result.toString(Charset.defaultCharset().toString());
}
System.out.println(pOut);
InputStream stdErr = p.getErrorStream();
// same with the error stream ...
int exit = p.waitFor();
System.out.println("Subprocess exited with " + exit);
Below is the program that will help you store the full output of any script or any command into String object.
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class ExecuteShellComand {
public static void main(String[] args) {
ExecuteShellComand obj = new ExecuteShellComand();
String output = obj.executeCommand("sh /opt/yourScriptLocation/Script.sh");
System.out.println(output);
}
private String executeCommand(String command) {
StringBuffer output = new StringBuffer();
Process p;
try {
p = Runtime.getRuntime().exec(command);
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();
}
return output.toString();
}
}
I just google it and there is a nice tutorial, full of examples here : http://www.mkyong.com/java/how-to-execute-shell-command-from-java/
I know people prefere copy/paste but let's respect other people's work and go on their website :p