Help with start a ssh session using java

Hi all,

I need to write a small java program to do the automate task. However, I couldn't get pass the first command in the task. The program is supposed to read back the question for password from the system. However, I always got nothing when run it.

Any help or advice?

import java.io.InputStream;

import java.io.OutputStream;

import java.io.DataInputStream;

import java.io.FileOutputStream;

import java.io.PrintStream;

import java.io.InputStreamReader;

import java.io.BufferedReader;

import java.io.IOException;

class TestSSH {

public static void main(String[] args) {

try {

Process process = Runtime.getRuntime().exec("ssh -l root 167.34.5.44");

InputStream in = process.getInputStream();

//InputStreamReader rin = new InputStreamReader(in);

//BufferedReader bin = new BufferedReader(rin);

OutputStream out = process.getOutputStream();

System.out.println("input, output stream setup");

int input;

DataInputStream dataIn = new DataInputStream(in);

FileOutputStream log = new FileOutputStream("log.txt");

PrintStream pLog = new PrintStream(log);

System.out.println("everything setup");

while (true ) {

if (dataIn == null) {

pLog.println("inputstream is null, exit");

System.exit(0);

}

//String s;

if ((input = dataIn.readInt()) != -1) {

pLog.print(input);

pLog.flush();

}

else {

break;

}

}

} catch (IOException e) {

System.out.println(e.getMessage());

}

}

}

[1626 byte] By [principlesa] at [2007-11-27 8:47:49]
# 1

When you post code, please wrap it in [code][/code] tags so it's easier to read.

It's unclear to me what you're trying to accomplish using DataInputStream. Do you really think that an int primitive will be sent by ssh?

Anyway, rather than trying to exec an ssh process, it would probably be easier to find a ssh implementation for Java. There must be one; try Google.

paulcwa at 2007-7-12 20:53:36 > top of Java-index,Java Essentials,Java Programming...
# 2

Thanks for your comment. As I said, this is the first step in my apps so it's not doing anything right now. All I want is just to make sure I could exec the command and get back the question for password from remote machine. However, while I could send the command successfully, the DataInputStream I used to get the response from remote machine is alway empty and I got stuck there.

It's not a matter for me now the format of the response. All I want is how to get the response.

Googling suggest some open source like jexpect. However, I couldn't find any place to download it. Anyone still keep a copy of the source? Please help.

principlesa at 2007-7-12 20:53:36 > top of Java-index,Java Essentials,Java Programming...
# 3

Well, again, why even use DataInputStream? Why ask it for an int? You say "It's not a matter for me now the format of the response" as if the output of ssh were somehow irrelevant.

There seems to be a Java SSH here:

http://sourceforge.net/projects/sshtools/

I've never used it but it looks reasonable enough.

If you insist on exec'ing ssh...then I'd suggest getting rid of DataInputStream, and reading just a sequence of characters. Wrap a Reader around the InputStream and read characters. DON'T use BufferedReader and try reading line-by-line, because ssh may prompt you (say, for a password) without sending a newline.

paulcwa at 2007-7-12 20:53:36 > top of Java-index,Java Essentials,Java Programming...
# 4

My problem is not the DataInputStream or any Wrapper Reader around the InputStream. I could use any of them, no preference. Actually you should see on my comment code that I tried with BufferedReader too. My problem here is I didn't receive anything from the InputStream. It's like the InputStream is alway empty. Strange enough, I saw the prompt for password on my screen but the InputStream was still empty.

Could you think of any reason?

principlesa at 2007-7-12 20:53:36 > top of Java-index,Java Essentials,Java Programming...
# 5

Yeah I saw the commented-out readers, I didn't know why you commented them out; they make more sense than a DataInputStream.

If the password prompt is appearing on your screen when you Runtime.exec ssh, and if you're not doing anything like grabbing standard output from the exec'd process and echoing it to standard output of the Java process, then it seems that the ssh process is not sending it's output to the standard output stream...rather, it seems to be grabbing the terminal, perhaps, and writing directly to it?

When you say the "screen", do you mean the current console/shell window, or do you mean that it's creating a new one and writing to that?

In any event, this seems to be some behavior specific to the ssh you're using. More reason to try using an ssh library instead.

paulcwa at 2007-7-12 20:53:36 > top of Java-index,Java Essentials,Java Programming...
# 6

Yes, it seems to be clearer to me now. The prompt message is output t o the current console/shell window. May be it's due to the fact that I'm using Putty from window to connect to a linux box.

So should I catch the standard input/output to get this message in order to process? I will try with it tomorrow. It's interesting to see that I could catch the error message by checking error output stream of the process.

About your advice, unfortunately I have very short time to do this and none of the library I googled so far is intuitive. The easiest I tried is ExpectJ but it didn't work, it has the same problem as my test program here. I'm looking for jexpect but it seems to be too old and I couldn't get the source code.

principlesa at 2007-7-12 20:53:36 > top of Java-index,Java Essentials,Java Programming...
# 7
Really thanks for your help. I finally could get what I want using some opensource ssh library around. I think I will stick with it to avoid hassle on shell command and inportabliity of code. Appreciate.
principlesa at 2007-7-12 20:53:36 > top of Java-index,Java Essentials,Java Programming...
# 8

Well, yeah, putty.exe creates a new command window when you start it. Runtime.exec'ing that wouldn't change that. So grabbing the standard output and error from the process wouldn't buy you much, although you should do it anyway -- read this:

http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html

Now, maybe, putty can take a command-line argument that makes it work only via standard i/o, in which case grabbing the standard i/o would help.

I really think that using a Java ssh library will be much easier overall.

Message was edited by:

paulcw

paulcwa at 2007-7-12 20:53:36 > top of Java-index,Java Essentials,Java Programming...