Im using java to start a GNOME terminal process in linux and redirecting its input and output to my code. Below is a code.
public static void main(String[] args) throws InterruptedException
{
// TODO Auto-generated method stub /usr/bin/telnet
try
{
String line, commandInput;
Scanner scan = new Scanner(new File("/home/Ashutosh/Documents/testfile"));
ProcessBuilder telnetProcessBuilder = new ProcessBuilder("/bin/bash");///home/Ashutosh/Documents/tempScript");
telnetProcessBuilder.redirectErrorStream(true);
Process telnetProcess = telnetProcessBuilder.start();
//Process telnetProcess = Runtime.getRuntime().exec("xterm");///home/Ashutosh/Documents/tempScript");
BufferedReader input = new BufferedReader(new InputStreamReader(telnetProcess.getInputStream()));
BufferedWriter output = new BufferedWriter(new OutputStreamWriter(telnetProcess.getOutputStream()));
while(scan.hasNext())
{
commandInput = scan.nextLine();
output.write(commandInput);
/* if(commandInput.trim().equals("exit"))
{
output.write("exit\r");
}
else
{
output.write("((" + commandInput + ") && echo --EOF--) || echo --EOF--\r");
}
*/ output.flush();
line = input.readLine();
while(line != null && !line.trim().equals("--EOF--"))
{
System.out.println(line);
line = input.readLine();
}
if(line == null)
break;
}
/* Thread.sleep(500);
output.write("/home/Ashutosh/Documents/testfile\r");
Thread.sleep(500);
output.flush();
while((line = input.readLine())!= null)
System.out.println(line);
telnetProcess.destroy();
*/ //String s = input.readLine();
//System.out.print(s + "\r\n");
//s = input.readLine();
//System.out.print(s + "\r\n");
}
the contents of testfile which is bash script is
#!/bin/bash
ls -l
pwd
date
exit
and i also tried the following interactive script which takes input from user which i want to redirect from java code is given
#! /bin/bash
echo "Input any number form 0-3:"
read num
case $num in
0) echo "You are useless";;
1) echo "You are number 1";;
2) echo "Too suspecious";;
3) echo "Thats all man, got to go...!";;
*) echo "Cant't u read english, this is wrong choice";;
esac
read
exit
my code stops at input.readLine(); im not sure but i think i am not able to redirect the output stream
output.write(commandInput);
command is executing well but did not write i intended to on the process redirected input, that is why it hangs at readLine();.
If somebody have already solved please let me know the solution.
From following link i tried to solve the issue but still no luck:
Java Process with Input/Output Stream
Thanks
Ashutosh
readLine() read the contents of a line, without the newline at the end.
write() writes just the text, it doesn't add a new line.
Perhaps you want to add write("\n"); or use PrintStream or PrintWriter.
I imagine, your script is being sent as
#!/bin/bashls -lpwddateexit
which is a comment without a newline.
EDIT: Huge error, not adding the command to the ProcessBuilder!!
Why are you not just running your script as a Linux script? That is,
ProcessBuilder builder = new ProcessBuilder();
LinkedList<String> command = new LinkedList<String>();
command.add("/bin/bash");
command.add("/home/Ashutosh/Documents/testfile");
builder.command(command);
Process myProc = builder.start();
Also, I notice the variable is named 'telnetProcess' yet there is no invocation of telnet anywhere that I can see. Perhaps this is the problem?
EDIT: Added my suggestion below for the interactive script.
ProcessBuilder builder = new ProcessBuilder();
LinkedList<String> command = new LinkedList<String>();
command.add("/bin/bash");
command.add("/path/to/interactiveScript");
builder.command(command);
final Process myProc = builder.start();
// Java input goes to process input.
Thread inputParser = new Thread() {
public void run() {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(myProc.getOutputStream()));
String line = "";
while(line != null) {
line = br.readLine();
bw.write(line);
bw.newLine();
}
}
}.start();
// Process output must go to Java output so user can see it!
Thread outputParser = new Thread() {
public void run() {
BufferedReader br = new BufferedReader(new InputStreamReader(myProc.getInputStream()));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
String line = "";
while(line != null) {
line = br.readLine();
bw.write(line);
bw.newLine();
}
}
}.start();
hi guys sorry for late response, after some trials i got it working. I am simply letting the process completing its process and exit normally rather than forcefully and then the BufferedReader and BufferedWriter keeps the string buffers in RAM which i can read now after process exit with code 0.
public static void main(String[] args) throws InterruptedException
{
// TODO Auto-generated method stub
try
{
String line, commandInput;
ProcessBuilder telnetProcessBuilder = new ProcessBuilder("/bin/bash");
telnetProcessBuilder.redirectErrorStream(true);
Process telnetProcess = telnetProcessBuilder.start();
BufferedReader input = new BufferedReader(new InputStreamReader(telnetProcess.getInputStream()));
BufferedWriter output = new BufferedWriter(new OutputStreamWriter(telnetProcess.getOutputStream()));
commandInput = "ls -l\n";
output.write(commandInput);
output.flush();
commandInput = "pwd\n";
output.write(commandInput);
output.flush();
commandInput = "whoami\n";
output.write(commandInput);
output.flush();
commandInput = "exit\n";
output.write(commandInput);
output.flush();
while((line = input.readLine())!= null)
System.out.println(line);
}
}
Related
My problem is, after opening cmd from java code, i want user to be able to input like in c++ ms dos applications. When user writes sth such as "dir" or "cd..", i want to execute these codes by java.
The problem is for every command java re-opens cmd again. Also i cannot execute commands. My cmd start code is below ;
final ArrayList<String> commands = new ArrayList<>();
commands.add("cmd.exe");
commands.add("/C");
commands.add("start");
ProcessBuilder pb = new ProcessBuilder(commands);
Process process = pb.start();
Here's some cleaned up code from How to open the command prompt and insert commands using Java?
public static void main(String[] args) {
try {
String ss = null;
Runtime obj = null;
Process p = Runtime.getRuntime().exec("cmd.exe");
//write a command to the output stream
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
writer.write("dir");
writer.flush();
//Get the input and stderror
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
System.out.println("Here is the standard output of the command:\n");
while ((ss = stdInput.readLine()) != null) {
System.out.println(ss);
}
System.out.println("Here is the standard error of the command (if any):\n");
while ((ss = stdError.readLine()) != null) {
System.out.println(ss);
}
} catch (IOException e) {
System.out.println("FROM CATCH" + e.toString());
}
}
I am trying to dump a MySQL database within my Java application the following way:
String[] command = new String[] {"cmd.exe", "/c", "C:/mysql/mysqldump.exe" --quick --lock-tables --user=\"root\" --password=\"mypwd\" mydatabase > \"C:/mydump.sql\""};
Process process = Runtime.getRuntime().exec(command);
int exitcode = process.waitFor();
The process fails with exit-code 6. I somewhere read that the operand ">" is not correctly interpreted and there was the hint to use "cmd.exe /c" as prefix. But it still doesn't work.
Any ideas?
Yes, you are right , some days ago I made class for exporting DataBase from MySQL...
You coud read output sream from console and then write to file
String[] command = new String[] {"cmd.exe", "/c", "\"C:/Program Files/MySQL/MySQL Server 5.6/bin/mysqldump.exe\" --quick --lock-tables --user=\"root\" --password=\"mypwd\" mydatabase "};
Process process = Runtime.getRuntime().exec(command);
BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
while ((line = input.readLine()) != null) {
System.out.println(line); //there you can write file
}
input.close();
Best Regards
Okay here's the final solution. You need to put the "process-reader to file-writer" code into a separate thread and finally wait for the process object to be finished:
// define backup file
File fbackup = new File("C:/backup.sql");
// execute mysqldump command
String[] command = new String[] {"cmd.exe", "/c", "C:/path/to/mysqldump.exe --quick --lock-tables --user=myuser --password=mypwd mydatabase"};
final Process process = Runtime.getRuntime().exec(command);
// write process output line by line to file
if(process!=null) {
new Thread(new Runnable() {
#Override
public void run() {
try{
try(BufferedReader reader = new BufferedReader(new InputStreamReader(new DataInputStream(process.getInputStream())));
BufferedWriter writer = new BufferedWriter(new FileWriter(fbackup))) {
String line;
while((line=reader.readLine())!=null) {
writer.write(line);
writer.newLine();
}
}
} catch(Exception ex){
// handle or log exception ...
}
}
}).start();
}
if(process!=null && process.waitFor()==0) {
// success ...
} else {
// failed
}
On Linux you can directly re-direct the output of the command to a file by using ">" as usual... (and also on Mac OS X I think). So no need for the thread. Generally, please avoid white spaces in your path to the mysqldump/mysqldump.exe file!
I want to get the IP address of logged in user of the telnet session
So I have written the following code:
Process p1 = Runtime.getRuntime().exec(new String[] {"/usr/bin/who", "-m"});
p1.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(p1.getInputStream()));
String line = reader.readLine();
System.out.println("line=" + line);
reader.close();
But I am getting the output as "null".
Where as expected output is:
linus pts/1 Dec 10 03:48 (172.21.235.48)
In this case you shouldn't pass the -m option.
This works for me :
Process p1 = Runtime.getRuntime().exec(new String[] {"/usr/bin/who"});
Try to consume the input stream from the process before calling waitFor().
You can create a shell script which will receive parameter (option) from your java program.
Then you can run your shell script from java like this -
ProcessBuilder pb = new ProcessBuilder("/PATH/test.sh","-m");
String line;
Process process=pb.start();
java.io.InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
while ((line = br.readLine()) != null)
{
System.out.println(line);
}
return br;
Now in test.sh, you cab grab the argument and run the command -
/usr/bin/who $1 (needs to check, not sure)
Hope this helps.
Thanks guys for the replies.
From the reply of "dystroy" I understood that -m was creating problem.
I tried --m and it worked :)
Please try this code. It's working for me and returns the same output as who -m UNIX command.
import java.io.*;
public class UserPB
{
public static void main(String[] args)
{
try {
// ProcessBuilder pb = new ProcessBuilder("/u01/app/chdir/user.sh");
ProcessBuilder pb = new ProcessBuilder("who");
Process p;
p = pb.start();
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
System.out.println("Your Host Details--->"+input.readLine());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I'm trying to get my program to launch Enchanter to SSH into my server, but can't seem to figure out how to get in and output to go to stdin and stdout, or anywhere for that matter. I just get a blank output window in Netbeans. How to I get the Jar to run, and get input/output?
public class openShell {
public void openShell() throws IOException {
String line;
Scanner scan = new Scanner(System.in);
ProcessBuilder builder = new ProcessBuilder ("C:\\Program Files\\Java\\lib\\enchanter-beanshell-0.6.jar", "myscript.bsh");
builder.redirectErrorStream(true);
Process process = builder.start();
OutputStream stdin = process.getOutputStream ();
InputStream stderr = process.getErrorStream ();
InputStream stdout = process.getInputStream ();
BufferedReader reader = new BufferedReader (new InputStreamReader(stdout));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stdin));
while (scan.hasNext()) {
String input = scan.nextLine();
if (input.trim().equals("exit")) {
// Putting 'exit' amongst the echo --EOF--s below doesn't work.
writer.write("exit\n");
} else {
writer.write("((" + input + ") && echo --EOF--) || echo --EOF--\n");
}
writer.flush();
line = reader.readLine();
while (line != null && ! line.trim().equals("--EOF--")) {
System.out.println ("Stdout: " + line);
line = reader.readLine();
}
if (line == null) {
break;
}
}
}
}
private void LaunchButtonActionPerformed(ActionEvent evt) {
//openShell open = new openShell(); //RUNS BUT NO IN OR OUTPUT
//BELOW CODE IS FOR TESTING, JUST TRYING TO GET PROCESSBUILDER TO CONNECT
// TO MY JAR
try {
ProcessBuilder builder = new ProcessBuilder(
"Java -jar C:\\Program Files\\Java\\lib\\enchanter-beanshell-0.6.jar");
builder.redirectErrorStream(true);
Process process = builder.start();
} catch (IOException ex) {
Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
The method ProcessBuilder.inheritIO will redirect your command streams in your stdin, stdout and stderr. This applies to Java 7.
String[] args = {
"java",
"-jar",
"C:\\Program Files\\Java\\lib\\enchanter-beanshell-0.6.jar"
};
ProcessBuilder builder = new ProcessBuilder(args);
Start with breaking up the arguments as above. Then implement all the recommendations of When Runtime.exec() won't.
The methods Process.getInputStream and Process.getOutputStream will get you streams that you can then read from and write to.
In Java, I want to be able to execute a Windows command.
The command in question is netsh. This will enable me to set/reset my IP address.
Note that I do not want to execute a batch file.
Instead of using a batch file, I want to execute such commands directly. Is this possible?
Here is my implemented Solution for Future Reference:
public class JavaRunCommand {
private static final String CMD =
"netsh int ip set address name = \"Local Area Connection\" source = static addr = 192.168.222.3 mask = 255.255.255.0";
public static void main(String args[]) {
try {
// Run "netsh" Windows command
Process process = Runtime.getRuntime().exec(CMD);
// Get input streams
BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(process.getErrorStream()));
// Read command standard output
String s;
System.out.println("Standard output: ");
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
// Read command errors
System.out.println("Standard error: ");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
} catch (Exception e) {
e.printStackTrace(System.err);
}
}
}
Runtime.getRuntime().exec("netsh");
See Runtime Javadoc.
EDIT: A later answer by leet suggests that this process is now deprecated. However, as per the comment by DJViking, this appears not to be the case: Java 8 documentation. The method is not deprecated.
Use ProcessBuilder
ProcessBuilder pb=new ProcessBuilder(command);
pb.redirectErrorStream(true);
Process process=pb.start();
BufferedReader inStreamReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
while(inStreamReader.readLine() != null){
//do something with commandline output.
}
You can run the command with Runtime.getRuntime().exec("<command>") (eg. Runtime.getRuntime().exec("tree")). But, this will only run executables found in path, not commands like echo, del, ... But only stuff like tree.com, netstat.com, ... To run regular commands, you will have to put cmd /c before the command (eg Runtime.getRuntime().exec("cmd /c echo echo"))
public static void main(String[] args) {
String command="netstat";
try {
Process process = Runtime.getRuntime().exec(command);
System.out.println("the output stream is "+process.getOutputStream());
BufferedReader reader=new BufferedReader( new InputStreamReader(process.getInputStream()));
String s;
while ((s = reader.readLine()) != null){
System.out.println("The inout stream is " + s);
}
} catch (IOException e) {
e.printStackTrace();
}
}
This works.
Runtime#exec().