I wrote a program which just runs a command on remote machine and then halts. There is a program:
import com.jcraft.jsch.*;
import java.io.*;
public class JSchTest {
private static String readString(String prompt) {
if (prompt != null) {
System.out.println(prompt);
}
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String input = null;
try {
input = in.readLine();
} catch (IOException e) {
System.err.println(e);
}
return input;
}
private static boolean readBoolean(String prompt) {
while (true) {
String input = readString(prompt);
if (input.equalsIgnoreCase("Y") || input.equalsIgnoreCase("N")) {
return input.equalsIgnoreCase("Y");
} else {
System.out.println("Enter Y or N.");
}
}
}
public static void main(String[] args) throws Exception {
JSch jsch = new JSch();
Session session = jsch.getSession(readString("Login:"),
readString("Server:"), Integer.parseInt(readString("Port:")));
session.setUserInfo(
new UserInfo() {
@Override
public String getPassphrase() {
return readString("Passphrase:");
}
@Override
public String getPassword() {
return readString("Password:");
}
@Override
public boolean promptPassword(String message) {
return readBoolean(message);
}
@Override
public boolean promptPassphrase(String message) {
return readBoolean(message);
}
@Override
public boolean promptYesNo(String message) {
return readBoolean(message);
}
@Override
public void showMessage(String message) {
System.out.println(message);
}
}
);
session.connect();
ChannelExec channel = (ChannelExec)session.openChannel("exec");
InputStream in = channel.getInputStream();
channel.setCommand(readString("Command:"));
channel.connect();
byte[] buffer = new byte[1024];
int bytes;
do {
while (in.available() > 0) {
bytes = in.read(buffer, 0, 1024);
System.out.print(new String(buffer, 0, bytes));
}
} while (!channel.isClosed());
channel.disconnect();
session.disconnect();
}
}
This program works fine when I'm using commands which produce output only, such as echo Hello
. But when I'm trying to pass in a command such as read VAR;echo You entered: $VAR
my program is running into infinite loop, because channel isn't closed and is waiting for an input.
Ok, so I got channel
's output stream to write an input for
OutputStream out = channel.getOutputStream();
and made i/o loop looking like this:
while (true) {
while (in.available() > 0) {
bytes = in.read(buffer, 0, 1024);
System.out.print(new String(buffer, 0, bytes));
}
if (channel.isClosed()) {
break;
} else if (true /* channel.isWaitingForInput() */) {
String output = readString(null) + "\n";
out.write(output.getBytes());
out.flush();
}
}
But as you can see - I have no information about what is happening on the channel's other side. Is there is an input which I must provide now, or not? So my program is asking for an input anytime, though even is not needed.
So there is a question - how can I know when I must pass in an input for a channel, or, maybe, how can I rewrite my program so it won't just only running a commands, but also providing an input for them, when needed (but halting at the end anyway)?