![](/img/trans.png)
[英]Using JAVA intercepting Jsch prompt for entering password in UNIX shell
[英]Getting shell prompt twice in Java JSch Shell
好的,我遇到了一个问题,shell 的响应非常不一致。 例如,欢迎消息可以有 2 个单独的响应。 出于某种原因,当我在此之后使用任何命令时,提示将在我的响应中出现两次。
我注意到只有在使用我自己的管道输入/输出流时才会出现这些问题。 当我使用System.in
和System.out
,这些问题根本不会发生。
下面是相关代码。
SSH连接.java
package com.displee.ssh;
import com.jcraft.jsch.*;
import java.util.function.Function;
public class SSHConnection {
private static final JSch JSCH_INSTANCE = new JSch();
private Session session;
private ShellSession shellSession;
public SSHConnection(String ip, String username, String password) {
try {
this.session = JSCH_INSTANCE.getSession(username, ip);
this.session.setPassword(password);
this.session.setConfig("StrictHostKeyChecking", "no");
} catch(Exception e) {
e.printStackTrace();
this.session = null;
}
}
public boolean connect() {
try {
session.connect();
return true;
} catch(Exception e) {
e.printStackTrace();
session.disconnect();
return false;
}
}
public boolean isConnected() {
return session.isConnected();
}
public void disconnect() {
session.disconnect();
}
public boolean startShellSession(Function<String, Void> callback) {
try {
shellSession = new ShellSession();
shellSession.start(session, callback);
return true;
} catch(Exception e) {
e.printStackTrace();
return false;
}
}
public void writeShellMessage(String message) {
shellSession.write(message + "\r\n");
}
}
ShellSession.java
package com.displee.ssh;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelShell;
import com.jcraft.jsch.Session;
import java.io.*;
import java.util.function.Function;
/**
* A class representing a shell session.
* @author Displee
*/
public class ShellSession {
/**
* If this session is running.
*/
private boolean running = true;
private PipedOutputStream poutWrapper;
private PipedInputStream pin = new PipedInputStream(4096);
private PipedInputStream pinWrapper = new PipedInputStream(4096);
private PipedOutputStream pout;
private String lastCommand;
/**
* Constructs a new {@code ShellSession} {@code Object}.
*/
public ShellSession() {
try {
pout = new PipedOutputStream(pinWrapper);
poutWrapper = new PipedOutputStream(pin);
} catch(Exception e) {
e.printStackTrace();
}
}
/**
* Start this shell session.
* @param session The ssh session.
*/
public void start(Session session, Function<String, Void> callback) {
ChannelShell shellChannel = null;
try {
shellChannel = (ChannelShell) session.openChannel("shell");
shellChannel.setInputStream(pin);
shellChannel.setOutputStream(pout);
shellChannel.connect();
} catch(Exception e) {
e.printStackTrace();
}
if (shellChannel == null) {
return;
}
final Channel channel = shellChannel;
Thread thread = new Thread(() -> {
while (running) {
try {
if (pinWrapper.available() != 0) {
String response = readResponse();
callback.apply(response);
}
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
}
channel.disconnect();
});
thread.setDaemon(true);
thread.start();
}
/**
* Stop this shell session.
*/
public void stop() {
running = false;
}
/**
* Send a message to the shell.
* @param message The message to send.
*/
public void write(String message) {
lastCommand = message;
try {
poutWrapper.write(message.getBytes());
} catch(IOException e) {
e.printStackTrace();
}
}
/**
* Read the response from {@code pinWrapper}.
* @return The string.
* @throws IOException If it could not read the piped stream.
*/
private synchronized String readResponse() throws IOException {
final StringBuilder s = new StringBuilder();
while(pinWrapper.available() > 0) {
s.append((char) pinWrapper.read());
}
return s.toString();
}
}
我的 JavaFX 控制器:
package com.displee.ui;
import com.displee.ssh.SSHConnection;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import java.net.URL;
import java.util.ResourceBundle;
public class Controller implements Initializable {
@FXML
private TextArea console;
@FXML
private TextField commandInput;
@Override
public void initialize(URL location, ResourceBundle resources) {
SSHConnection connection = new SSHConnection("host", "username", "password");
connection.connect();
connection.startShellSession(s -> {
console.appendText(s);
return null;
});
commandInput.setOnAction(x -> {
connection.writeShellMessage(commandInput.getText());
commandInput.clear();
});
}
}
完整代码: https : //displee.com/upload/SSHProject.zip
我尝试增加输入流的大小,但这没有用。
这个问题真的让我很沮丧。 如果有人知道我如何解决我的问题,我将不胜感激。
注意:我还注意到使用我的管道流时它很慢。 我怎样才能加快速度?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.