Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

execute a shell command from java 1

Status
Not open for further replies.

mackey333

Technical User
May 10, 2001
563
US
since a java console app is running in a shell prompt, is there anyway to pass focus to the shell, execute a command, and then return to the java program thread? -Greg :-Q

flaga.gif
 
Hi mackey:

Off course it is. You can get a pointer to the command shell (the environment in which the application is running)through the RunTime class as follows:

RunTime r=RunTime.getRuntime();


With this pointer you can invoke the exec method with the proper parameters to execute a shell command.

for example:

Process proc=r.exec("ls");
BufferedStream stream = Process.getInputStream();


This lines calls a directory list from the commmand, and you can get the results through the stream received from the Process created.

The method waitFor() of the Process class will stop execution of current thread until the command is finished.



There is another tip, if you are running over a windows system, be sure to place a "command " string before any command you execute. This calls the windows command enviroment to execute the specific instruction.

Hope it helps.
 
thanks for the reply but it is not working, it says cannot resolve symbol on the RunTime r = RunTime.getRuntime(); do i need to import a package? -Greg :-Q

flaga.gif
 
still not working, here is the exception that was thrown by pedro's code...

java.gif
-Greg :-Q

flaga.gif
 
ok i got it to work now, but that is not exactly what i want to do...i want it so that if i have:

Process p = r.exec("cmd cls");

then the cls command is executed as if it was accually entered in the command prompt -Greg :-Q

flaga.gif
 
Hi mackey:

Sorry for the "RunTime", my mother's tongue is the spanish (as you can see in my poor english) and for me Run and Time are different words (for "tiempo de ejecucion" in spanish), so I get confused sometimes with the java standard for class names. Ok, after the disclaimer, lets check your app.

The code I posted has another error, in the getInputStream method wich I called from the Process class instead of the proc variable. I think you fixed it yet. I think the first error you received was because you were trying to execute "ls" in a windows system, which wont work most of the time.

I haven't too much experience with the windows console and Java, but I think that if you execute cls from an application launched from a console it wont clear the app's console, but another console instance, created at the getRuntime() method invocation. I don't know how to clear the app's console, but, if you want an easy solution (not the right one, but works) you can simply do the following:


for(int i=0;i<24;i++) System.out.println(&quot;&quot;);


Where the 24 is the number of lines of your console.
I know this is ugly, but if you just want your console cleared, it will work.

Hope it helps.

Pedro.
 
Yes, but that leaves another problem. Now we have the cursor stuck on the last line of console. Does java have a locate() method?. Or, is there a way to accually close the console java is running in and open another window and continue the execution in the new window? -Greg :-Q

flaga.gif
 
Hi Mackey:

You really made me think. I was wondering how to solve your problem, and I came up with a few ideas.
First, why are you working with the console? Java is improved to work with interactive interfaces, so you wont find methods as gotoxy in c to create awesome text-based interfaces.
If you use a JTextArea you can replace your System.out.println calls with textarea.append and you can manage the textarea view. But it changes the input methods, because you are now dealing with a graphical interface, so you can't do System.in.read to get user input, you must use events and ActionListeners and so on. If you have a long program that uses the console to interface with the user it could be a problem.
Well, with this in mind I write an adapter in swing for the system shell. I mean the console. Check this main first:

Code:
import java.io.IOException;
public class Test
{
		System.out.println(&quot;Hello World!... press enter.&quot;);
		try{System.in.read();}catch(IOException e){}
		System.out.println(&quot;You pressed enter. Press again to clear the console...&quot;);
		try{System.in.read();
		    System.in.read();}catch(IOException e){}
		for(int i=0;i<24;i++) System.out.println(&quot;&quot;);
		System.out.println(&quot;Console cleared...&quot;);
		System.out.println(&quot;Press again to exit...&quot;);
		try{System.in.read();
  		    System.in.read();}catch(IOException e){}
		System.exit(0);
	}
}

This program just prints some messages and expects some user input. It has double in.read because the enter key are represented by two characters, carriage return (\r) and new line, so you must read two characters to catch an enter. Well, this program has the cursor problem. But the System in and out are constant streams, it is not easy to deal graphically with them. So I write an adapter. check this class:


Code:
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JTextArea;

import java.io.InputStream;
import java.io.PrintStream;

import java.io.PipedInputStream;
import java.io.PipedOutputStream;

import java.io.BufferedReader;
import java.io.InputStreamReader;

import java.io.DataOutputStream;

import java.io.IOException;

public class Consola extends JFrame implements KeyListener, Runnable
{
	private PipedOutputStream out;
	private PipedInputStream out_in;


	private PipedInputStream in;
	private PipedOutputStream in_out;

	private DataOutputStream in_outWriter; 
	private BufferedReader out_inReader; 

	private JTextArea consola=new JTextArea();
	private Thread internal=new Thread(this);

	private int charCount=0;

	public void clear(){
		consola.replaceRange(&quot;&quot;, 0, charCount);
		charCount=0;
	}

	public Consola(){
		try{
			this.out_in=new PipedInputStream();
			this.out=new PipedOutputStream(out_in);
			this.in=new PipedInputStream();
			this.in_out=new PipedOutputStream(in);

		}catch(IOException e){
			System.out.println(&quot;Excepcion: \n&quot;+e);
		}
		out_inReader = new BufferedReader(new InputStreamReader(out_in));
		in_outWriter=new DataOutputStream(in_out);

		System.setIn((InputStream)in);
		System.setOut(new PrintStream(out));

                //SWING
		this.getContentPane().setLayout(null);
		setTile(&quot;Intercepted Console&quot;)
		setBounds(100,100,400,500);
		consola.setBounds(0,0,400,500);
		this.getContentPane().add(consola);
		consola.addKeyListener(this);
		consola.setEditable(false);
		consola.setBackground(Color.black);
		consola.setForeground(Color.white);
		internal.start();
		show();
	}

	public void run(){
		while(true){
			try{
				String input=&quot;&quot;;
				input=&quot;&quot;+out_inReader.readLine();
				consola.append(&quot;&quot;+input+&quot;\n&quot;);
				charCount+=input.length()+1; // +1: the \n
			}catch(IOException e){}
		}
	}


	public void keyTyped(KeyEvent e){
		try{
			in_outWriter.writeChar(e.getKeyChar());
		}catch(IOException ioe){}
	}


	public void keyPressed(KeyEvent e){}

	public void keyReleased(KeyEvent e){}
}

Looks a little weird, but is an easy concept. This class just reassigns the stdin and stdout to a pair of streams. Then it connects this streams through pipedstreams to another pair of streams (out/in). Then, it catch every character in the System.out stream and put it in a JTextArea with a runnable task, and catch every key pressed in the textarea with a KeyListener and write it to the System.in stream.
Result of the operation: you have your console intercepted by the textarea without losing functionality.
The textarea is editable(false) so the user can't modify the text entered. If you want an echo you can just write in the output anything on the input, in the keyTyped method. It would be nice to add scroll bars to the textArea too.

So we can now write the function to clear the console, just replacing the text entered with &quot;&quot;.

Check this new main:

Code:
import java.io.IOException;
public class Test
{

	Consola console = new Consola();
		System.out.println(&quot;Hello World!... press enter.&quot;);
		try{System.in.read();}catch(IOException e){}
		System.out.println(&quot;You pressed enter. Press again to clear the console...&quot;);
		try{System.in.read();
		    System.in.read();}catch(IOException e){}
	console.clear();
		System.out.println(&quot;Console cleared...&quot;);
		System.out.println(&quot;Press again to exit...&quot;);
		try{System.in.read();
  		    System.in.read();}catch(IOException e){}
		System.exit(0);
	}
}


You just have to create a new instance of the Consola class (so it will intercept the System. calls), and call clear() instead of the println(&quot;&quot;) for. Problem solved.

This is just a test work, but it could be improved a lot. As we have graphic control over the textarea we can for example create the gotoxy(x,y) function using the insert(String, int, int) method of the JTextArea to print the characters. And anything else you may want to do with the console, like a java version of the c's conio.h library (reduced obviously).

Post any question you may have.

Hope it helps. Have fun.
 
I am using console because I'm taking a java class in school and he didnt teach us any other display methods yet, so even though I know how to do other things besides console, I am confined to it. I will try your code out and get back to you thanks. -Greg :-Q

flaga.gif
 
To all &quot;New to Java&quot; guys,

pedrosolorzano's code is excellent. The only thing missing is a main method in the Test class which enables you to run it. Basically, just all the code in between the class declaration into a &quot;main&quot; method.

pedrosolorzano - thank you for that code. Your way of thinking has given me loads of ideas for another application that I'm designing.

Cheers and Merry Festive Season to all,
Clinton
&quot;The important thing is not to stop questioning.&quot; - Albert Einstein
 

That's right rocknrisk! copy paste problems, let me say...

The correct Test class:

Code:
import java.io.IOException;
public class Test
{

  public static void main(String peter[]){
    Consola console = new Consola();
        System.out.println(&quot;Hello World!... press enter.&quot;);
        try{System.in.read();}catch(IOException e){}
        System.out.println(&quot;You pressed enter. Press again to clear the console...&quot;);
        try{System.in.read();
            System.in.read();}catch(IOException e){}
    console.clear();
        System.out.println(&quot;Console cleared...&quot;);
        System.out.println(&quot;Press again to exit...&quot;);
        try{System.in.read();
              System.in.read();}catch(IOException e){}
        System.exit(0);
    }
}

Hey mackey, I understand you now, and if you are confined to the console there's no much we can do about it... good luck.

Merry Christmas to all...
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top