Executor exec = new DefaultExecutor();
exec.setWorkingDirectory("/var/java/apache-tomcat-7.0.47/webapps/Telegram/tg")
CommandLine cl = new CommandLine("bin/telegram-cli -k tg-server.pub -W -U root");
int exitvalue = exec.execute(cl);
How can I get output of this command:
exec.execute(cl);
and run other related commands on telegram-cli command prompt e.g. contact_list, msg contact "Hello world";
It looks to me as though it would be easier just to use ProcessBuilder instead.
ProcessBuilder pb = new ProcessBuilder("bin/telegram-cli","-k","tg-server.pub","-W","-U","root");
pb.directory(new File("/var/java/apache-tomcat-7.0.47/webapps/Telegram/tg"));
Process p = pb.start();
try (BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
PrintWriter pw = new PrintWriter(new OutputStreamWriter(p.getOutputStream()),true)) {
String line = null;
pw.println("contact_list");
while ((line = br.readLine()) != null) {
System.out.println("line = " + line);
}
}
Update
It looks like the writes with PrintWriter need to be flushed. You can do this by calling pw.flush() or adding the second argument true to the PrintWriter constructor. I don't know the commands for telegram-cli, but you need to add one that will produce an output you can use to identify when to quit. Here's an example using /bin/sh.
ProcessBuilder pb = new ProcessBuilder("/bin/sh");
Process p = pb.start();
try (BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
PrintWriter pw = new PrintWriter(new OutputStreamWriter(p.getOutputStream()),true)) {
String line = null;
pw.println("ls");
pw.println("pwd");
pw.println("echo quit"); // this gives me output I can test for to break the loop
pw.flush();
while ((line = br.readLine()) != null && !line.contains("quit")) {
System.out.println("line = " + line);
}
}
int retcode = p.waitFor();
System.out.println("process ended with " + retcode);
Produces this output:
line = build
line = build.xml
line = dist
line = manifest.mf
line = nbproject
line = src
line = /home/shackle/NetBeansProjects/JavaApplication20
process ended with 0
Related
I executed a shell using:
Process process = Runtime.getRuntime().exec("docker exec rabbitmq bash");
But now, I want to execute another command inside the opened shell:
Writer w = new OutputStreamWriter(process.getOutputStream(), "UTF-8");
w.write("rabbitmqctl list_queues\n");
w.flush();
But I can't get the output of rabbitmqctl list_queues
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
I don't get any errors, if I use a malformed command, it will issue an error message:
BufferedReader error = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String errorString = error.readLine();
System.out.println("\nError : " + errorString);
int exitCode = process.waitFor();
The problem was the lack of use of -i parameter:
Process process = Runtime.getRuntime().exec("docker exec -i rabbitmq bash");
But, using only Process class I had had problems, the interpreter didn't understand the end of output and the loop didn't stop:
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
But using ProcessBuilder it worked:
#Test
void test_process_builder() throws IOException {
ProcessBuilder builder = new ProcessBuilder("docker","exec","-i","rabbitmq3","bash");
Process process = builder.start();
OutputStream stdin = process.getOutputStream(); // <- Eh?
InputStream stdout = process.getInputStream();
InputStream stderr = process.getErrorStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(stdout));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stdin));
BufferedReader error = new BufferedReader(new InputStreamReader(stderr));
writer.write("rabbitmqctl list_queues \n");
writer.flush();
writer.close();
Scanner err = new Scanner(stderr);
while (err.hasNextLine()) {
System.out.println(err.nextLine());
}
Scanner scanner = new Scanner(stdout);
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
}
}
I want to get terminal history
So I did this
Runtime rt = Runtime.getRuntime();
pr = rt.exec("/bin/bash -c \"history -c\"");
pr.waitFor();
rt.exec("/usr/bin/xterm");
but there is problem with pr = rt.exec("/bin/bash -c \"history -c\""); , it's not clearing the previous history nither of xterm nor my normal terminal.
Also when I try to print the history it returns nothing (no errors)
p = Runtime.getRuntime().exec("/bin/bash -c \"history\"");
p.waitFor();
BufferedReader reader =
new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
System.out.println("printing");
while ((line = reader.readLine())!= null) {
output.append(line + "\n");
}
I also tried
String[] commands = new String[]{"/bin/sh","-c", "history -c" ,"xterm"};
try {
Process proc = new ProcessBuilder(commands).start();
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(proc.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(proc.getErrorStream()));
} catch (IOException e1) {
e1.printStackTrace();
}
still not clearing history.
You can remove the history file yourself by getting the $HISTFILE environment variable. This will always get the correct history file for different shells. I believe the issue you're having is that the you may be using a different shell or have changed your history file location.
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class RemoveShellHistory {
public static void main(String[] args) {
RemoveShellHistory obj = new RemoveShellHistory();
final String shellPath = System.getenv("SHELL");
String shell = shellPath.substring(shellPath.lastIndexOf("/")+1, shellPath.length());
final String home = System.getenv("HOME");
String command = "rm -v " + home + "/." + shell + "_history";
String output = obj.executeCommand(command);
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();
}
}
Assuming that your java app runs by the same user possessing the .bash_history file:
To delete.
new File(System.getProperty("user.home"), ".bash_history").delete();
To clean (Handle the checked exception at your will).
FileWriter writer = new FileWriter(
new File(System.getProperty("user.home"), ".bash_history"));
writer.write("");
writer.close();
We are trying to call a Powershell script via Java but it hangs when we try to read the output of that script. It hangs on "input.readLine()"
Here is a code we have tried:
String command = "cmd /c powershell C:\\_checkouts\\TestPowerShell\\passwordExpirationTime.ps1";
Process p = Runtime.getRuntime().exec(command);
new InputStreamReader(p.getInputStream());
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
StringBuilder stringBuilder = new StringBuilder();;
for (String line = input.readLine(); line != null; line = input.readLine()) {
stringBuilder.append(line);
}
input.close();
String msg = stringBuilder.toString();
System.out.println("msg: " + msg);
We tried looking at this solution Java program hangs when trying to invoke powershell script
but none of those suggestions worked for us.
We also tried it without cmd /c and with cmd /k. We really want this as a generic class where any script could be called. i.e. BAT, BASH, SH, Powershell, etc.
Any ideas?
Thanks to the answer below here is the code that worked:
try{
final ProcessBuilder pb = new ProcessBuilder("powershell","C:\\psFile.ps1");
pb.redirectInput(Redirect.from(new File("NUL")));
final Process p = pb.start();
final int retcode = p.waitFor();
InputStream is = p.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
}catch (Exception e){
e.printStackTrace();
}
Here's some additional information. Our powershell was returning an error because it was restricted. That is why we needed all the Redirect to NUL. Once we fixed that and it wasn't returning an error we were able to simplify our code to this:
try{
final ProcessBuilder pb;
pb = new ProcessBuilder(args);
final Process p = pb.start();
InputStream is = p.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
}catch (Exception e){
e.printStackTrace();
}
Use a ProcessBuilder. Any process implying a modicum of I/O should outright refuse to run via Runtime.exec(), alas, it cannot detect that. And Oracle hasn't flagged it as #Deprecated which is a pity.
Anyway:
final File logFile = new File("/path/to/logfile");
final ProcessBuilder pb = new ProcessBuilder("powershell", "/path/to/the/ps1");
pb.redirectOutput(Redirect.to(logFile));
pb.redirectErrorStream(true);
final Process p = pb.start();
final int retcode = p.waitFor();
// deal with retcode
// read result from the log file
I want to use two Runtime in same method. The second uses the result of the first. I return the results of in two files (*.txt). The result of execution of the first is ok, but the file of the second is empty.
The code used is given below:
public void applicationpackage() {
try {
Process process = Runtime.getRuntime().exec(
new String[] { "/bin/sh", "-c",
"ls " + pathPackage + "/*.apk" });
process.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(
process.getInputStream()));
File f = new File(pathPackage + "/packagename.txt");
PrintWriter writer = new PrintWriter(f, "UTF-8");
String line = reader.readLine();
while ((line != null)) {
System.out.println(line);
applicationPackage.add(line);
writer.println(line);
line = reader.readLine();
Process p = Runtime.getRuntime().exec(new String[]{
"/bin/sh", "-c", "cut -d. -f2,3 <<<" + line
});
p.waitFor();
BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
File file = new File(pathPackage +"/application.txt");
PrintWriter w = new PrintWriter(file, "UTF-8");
String l = r.readLine();
while(l!= null){
w.println(l);
w.println("toto");
l = r.readLine();
}
name+= "cut -d. -f2,3 <<<" + line +" &";
System.out.println("toto" + name);
}
System.out.println("toto" + name);
writer.close();
} catch (IOException | InterruptedException e1) { }
}
If your file is empty, it usually means your PrintWriter has not got autoflush set, or you have not closed the writer. The last reference to w is w.println("toto");. Add w.close() to your code.
Also when you instantiate a PrintWriter you should pass in a boolean value at the constructor level to indicate that the PrintWriter should flush after every operation.
I would like to run a windows command line command from java and return the result into java. Is this possible?
for example, I would like to do the following
Object returnValue = runOnCommandLine("wmic cpu get LoadPercentage");
//In this case, returnValue is the cpu load percent as a String
Edit: I was able to get this working
InputStream inputStream = new ProcessBuilder("wmic", "cpu", "get", "status").start().getInputStream();
StringWriter writer = new StringWriter();
IOUtils.copy(inputStream, writer);
String theString = writer.toString();
System.out.println("My string: " + theString);
Data you need is commandOutput.
String cmd = "wmic cpu get LoadPercentage";
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.redirectErrorStream(true);
Process p = pb.start();
BufferedReader stdin = new BufferedReader(
new InputStreamReader(p.getInputStream()));
StringBuilder commandOutput = new StringBuilder();
String line;
while ((line = stdin.readLine()) != null) {
commandOutput.append(line);
}
int exitValue = -1;
try {
exitValue = p.waitFor();
} catch (InterruptedException e) {
// do something here
}
You could do the following:
Process proc = Runtime.getRuntime().exec("net start");
InputStreamReader isr = new InputStreamReader(proc.getInputStream());
BufferedReader br = new BufferedReader(isr);
String temp = null;
while (( temp = br.readLine() ) != null)
System.out.println(temp);
Take a look into ProcessBuilder.
Below Java 1.5 Runtime.getRuntime().exec(...) was used.