使用 Jsch 在交互模式下将 java textarea 作为 运行 shell 命令的输入流
Make java textarea as Inputstream to run shell command in interactive mode using Jsch
您好,我正在使用 Jsch 来 运行 我的 shell 命令。我想让它具有交互性。我正在使用 java textarea 来显示 script.This 脚本的输出,也需要一些用户输入。 我怎样才能让这个文本区域接受用户输入和运行命令。
public void init(){
try{
JSch jsch=new JSch();
Panel panel = new Panel();
TextArea log = new TextArea();
panel.add(log);
add(panel);
PrintStream printStream = new PrintStream(new CustomOutputStream(log));
System.setOut(printStream);
System.setErr(printStream);
Session session=jsch.getSession("akumar", "banas", 22);
String passwd = "*****";
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.setPassword(passwd);
session.connect(30000); // making a connection with timeout.
Channel channel=session.openChannel("shell");
channel.setInputStream(System.in);
channel.setOutputStream(System.out);
channel.connect(3*1000);
printStream.println("sftp akumar@banas");
printStream.flush();
}
catch(Exception e){
System.out.println(e);
}
}
// This is the code for making textarea as output stream
public class CustomOutputStream extends OutputStream {
private TextArea textArea;
public CustomOutputStream(TextArea textArea) {
this.textArea = textArea;
}
@Override
public void write(int b) throws IOException {
// redirects data to the text area
textArea.append(String.valueOf((char)b));
// scrolls the text area to the end of data
textArea.setCaretPosition(textArea.getText().length());
}
}
这是一种使用 BlockingQueue 将数据从 JTextField 的 actionListener 传递到 CustomInputStream 的方法。
public class Main extends JFrame {
public Main() {
init();
}
public void init() {
try {
JSch jsch = new JSch();
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(200, 200));
JTextArea log = new JTextArea();
JTextField cmd = new JTextField();
panel.setLayout(new BorderLayout());
JScrollPane scrollPane = new JScrollPane(log);
panel.add(scrollPane, BorderLayout.CENTER);
panel.add(cmd, BorderLayout.SOUTH);
add(panel);
Session session = jsch.getSession("akumar", "banas", 22);
String passwd = "******";
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.setPassword(passwd);
session.connect(30000); // making a connection with timeout.
Channel channel = session.openChannel("shell");
channel.setInputStream(new CustomInputStream(cmd));
channel.setOutputStream(new CustomOutputStream(log));
channel.connect(3 * 1000);
pack();
} catch (Exception e) {
System.out.println(e);
}
}
public class CustomInputStream extends InputStream implements ActionListener {
final JTextField field;
final BlockingQueue<String> q;
public CustomInputStream(JTextField field) {
this.field = field;
q = new LinkedBlockingQueue<>();
field.addActionListener(this);
}
private String s;
int pos;
@Override
public int read() throws IOException {
while (null == s || s.length() <= pos) {
try {
s = q.take();
pos = 0;
} catch (InterruptedException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
int ret = (int) s.charAt(pos);
pos++;
return ret;
}
@Override
public boolean markSupported() {
return false;
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
int bytes_copied = 0;
while (bytes_copied < 1) {
while (null == s || s.length() <= pos) {
try {
s = q.take();
System.out.println("s = " + s);
pos = 0;
} catch (InterruptedException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
int bytes_to_copy = len < s.length()-pos ? len : s.length()-pos;
System.arraycopy(s.getBytes(), pos, b, off, bytes_to_copy);
pos += bytes_to_copy;
bytes_copied += bytes_to_copy;
}
return bytes_copied;
}
@Override
public int read(byte[] b) throws IOException {
return read(b, 0, b.length); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void actionPerformed(ActionEvent e) {
q.add(field.getText() + "\r\n");
field.setText("");
}
}
// This is the code for making textarea as output stream
public class CustomOutputStream extends OutputStream {
private JTextArea textArea;
public CustomOutputStream(JTextArea textArea) {
this.textArea = textArea;
}
@Override
public void write(int b) throws IOException {
// redirects data to the text area
textArea.append(String.valueOf((char) b));
// scrolls the text area to the end of data
textArea.setCaretPosition(textArea.getText().length());
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
String s = new String(b,off,len);
textArea.append(s);
textArea.setCaretPosition(textArea.getText().length());
}
@Override
public void write(byte[] b) throws IOException {
this.write(b, 0, b.length);
}
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(() -> {
new Main().setVisible(true);
});
}
}
您好,我正在使用 Jsch 来 运行 我的 shell 命令。我想让它具有交互性。我正在使用 java textarea 来显示 script.This 脚本的输出,也需要一些用户输入。 我怎样才能让这个文本区域接受用户输入和运行命令。
public void init(){
try{
JSch jsch=new JSch();
Panel panel = new Panel();
TextArea log = new TextArea();
panel.add(log);
add(panel);
PrintStream printStream = new PrintStream(new CustomOutputStream(log));
System.setOut(printStream);
System.setErr(printStream);
Session session=jsch.getSession("akumar", "banas", 22);
String passwd = "*****";
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.setPassword(passwd);
session.connect(30000); // making a connection with timeout.
Channel channel=session.openChannel("shell");
channel.setInputStream(System.in);
channel.setOutputStream(System.out);
channel.connect(3*1000);
printStream.println("sftp akumar@banas");
printStream.flush();
}
catch(Exception e){
System.out.println(e);
}
}
// This is the code for making textarea as output stream
public class CustomOutputStream extends OutputStream {
private TextArea textArea;
public CustomOutputStream(TextArea textArea) {
this.textArea = textArea;
}
@Override
public void write(int b) throws IOException {
// redirects data to the text area
textArea.append(String.valueOf((char)b));
// scrolls the text area to the end of data
textArea.setCaretPosition(textArea.getText().length());
}
}
这是一种使用 BlockingQueue 将数据从 JTextField 的 actionListener 传递到 CustomInputStream 的方法。
public class Main extends JFrame {
public Main() {
init();
}
public void init() {
try {
JSch jsch = new JSch();
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(200, 200));
JTextArea log = new JTextArea();
JTextField cmd = new JTextField();
panel.setLayout(new BorderLayout());
JScrollPane scrollPane = new JScrollPane(log);
panel.add(scrollPane, BorderLayout.CENTER);
panel.add(cmd, BorderLayout.SOUTH);
add(panel);
Session session = jsch.getSession("akumar", "banas", 22);
String passwd = "******";
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.setPassword(passwd);
session.connect(30000); // making a connection with timeout.
Channel channel = session.openChannel("shell");
channel.setInputStream(new CustomInputStream(cmd));
channel.setOutputStream(new CustomOutputStream(log));
channel.connect(3 * 1000);
pack();
} catch (Exception e) {
System.out.println(e);
}
}
public class CustomInputStream extends InputStream implements ActionListener {
final JTextField field;
final BlockingQueue<String> q;
public CustomInputStream(JTextField field) {
this.field = field;
q = new LinkedBlockingQueue<>();
field.addActionListener(this);
}
private String s;
int pos;
@Override
public int read() throws IOException {
while (null == s || s.length() <= pos) {
try {
s = q.take();
pos = 0;
} catch (InterruptedException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
int ret = (int) s.charAt(pos);
pos++;
return ret;
}
@Override
public boolean markSupported() {
return false;
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
int bytes_copied = 0;
while (bytes_copied < 1) {
while (null == s || s.length() <= pos) {
try {
s = q.take();
System.out.println("s = " + s);
pos = 0;
} catch (InterruptedException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
int bytes_to_copy = len < s.length()-pos ? len : s.length()-pos;
System.arraycopy(s.getBytes(), pos, b, off, bytes_to_copy);
pos += bytes_to_copy;
bytes_copied += bytes_to_copy;
}
return bytes_copied;
}
@Override
public int read(byte[] b) throws IOException {
return read(b, 0, b.length); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void actionPerformed(ActionEvent e) {
q.add(field.getText() + "\r\n");
field.setText("");
}
}
// This is the code for making textarea as output stream
public class CustomOutputStream extends OutputStream {
private JTextArea textArea;
public CustomOutputStream(JTextArea textArea) {
this.textArea = textArea;
}
@Override
public void write(int b) throws IOException {
// redirects data to the text area
textArea.append(String.valueOf((char) b));
// scrolls the text area to the end of data
textArea.setCaretPosition(textArea.getText().length());
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
String s = new String(b,off,len);
textArea.append(s);
textArea.setCaretPosition(textArea.getText().length());
}
@Override
public void write(byte[] b) throws IOException {
this.write(b, 0, b.length);
}
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(() -> {
new Main().setVisible(true);
});
}
}