本工具模仿putty 实现了简单的ssh 远程交互功能。
本工具可嵌入到集群管理工具
目前尚在探索,错误之处欢迎指正
主干代码如下
转载注明:http://www.blogjava.net/roymoro/archive/2012/08/12/385318.html
1package cn.edu.neu.neuInfo.until.shell;
2
3import java.io.BufferedReader;
4import java.io.IOException;
5import java.io.InputStream;
6import java.io.InputStreamReader;
7import java.io.OutputStream;
8import java.io.OutputStreamWriter;
9import java.io.PrintStream;
10import java.io.PrintWriter;
11import java.io.UnsupportedEncodingException;
12import java.util.Scanner;
13
14import javax.swing.JTextArea;
15
16
17
18import ch.ethz.ssh2.ChannelCondition;
19import ch.ethz.ssh2.Connection;
20import ch.ethz.ssh2.ConnectionInfo;
21import ch.ethz.ssh2.Session;
22
23public class LinuxFSTool {
24 private static Connection con;
25 private static Session session;
26 private static PrintWriter out;
27 static ReadThread rt;
28 static ReadThread rt2;
29 static OutputStream outStream;
30 private static String address,username,password;
31 private static NeuInfoConfigration neuInfoConfig=NeuInfoConfigration.getInstance("linuxTool.properties");
32
33 public static boolean setConnect(String username,String password,String address) throws IOException{
34 LinuxFSTool.address=address;
35 LinuxFSTool.username=username;
36 LinuxFSTool.password=password;
37 return connectFS();
38 }
39 public static boolean isconnected()
40 {
41 if(con==null) return false;
42 return true;
43 }
44 public static boolean connectFS() throws IOException{
45 if(address==null||address.equals(""))
46 address=neuInfoConfig.getvalue(Parameters.Linux_ADDRESS.name);
47 if(username==null||username.equals(""))
48 username=neuInfoConfig.getvalue(Parameters.Linux_USERNAME.name);
49 if(password==null||password.equals(""))
50 password=neuInfoConfig.getvalue(Parameters.Linux_PASSWORD.name);
51 System.out.println(address+":"+username+":"+password);
52 con = new Connection(address);
53 ConnectionInfo info = con.connect();
54 //System.out.println(info.serverHostKey);
55 boolean result = con.authenticateWithPassword(username, password);
56 if(result==false){ con.close();con=null;}
57 return result;
58 }
59 public static void disconnectFS() throws IOException{
60 if(rt.isAlive()){
61 rt.stopThread();
62 }
63 if(rt2.isAlive()){
64 rt2.stopThread();
65 }
66 session.close();
67 con.close();
68 session=null;
69 con=null;
70 }
71 private static void shellRun(OutputStream outStream,JTextArea jta){
72 LinuxFSTool.outStream=outStream;
73 try{
74 if(con==null) connectFS();//如果未连接 则连接
75 session = con.openSession();
76 session.requestPTY("bash");
77 session.startShell();
78 InputStream in=session.getStdout();
79 rt=new ReadThread(in,new PrintStream(outStream),jta);
80 rt2=new ReadThread(session.getStderr(),new PrintStream(outStream),jta);
81 rt.start();
82 rt2.start();
83 out = new PrintWriter(new OutputStreamWriter(session.getStdin(),"UTF-8"));
84 } catch (Exception ex) {
85 System.out.println(ex.getLocalizedMessage());
86 ex.printStackTrace();
87 }
88 }
89 public static void executeCommand(String command){
90 executeCommand(command,System.out,null);
91 }
92 /** *//**
93 * use these instead of {@link LinuxFSTool#executeCommand(String)}
94 * @param command
95 * @param outStream
96 */
97 public static void executeCommand(String command,OutputStream outStream,JTextArea jta){
98
99 if(session==null)
100 shellRun(outStream,jta);
101 if(!command.equals("")) {
102 out.println(command);}
103 out.flush();
104 if(command.endsWith("bye")){
105 closeShell();
106 }
107
108 // System.out.println(session.getExitStatus());
109
110 }
111 private static void closeShell(){
112 session.close();
113 session.waitForCondition(ChannelCondition.CLOSED | ChannelCondition.EOF | ChannelCondition.EXIT_STATUS, 30000);
114 //StringBuilder sb=new StringBuilder();\
115 System.out.println("byebye");
116 }
117 /** *//**
118 * test
119 * @param args
120 * @throws IOException
121 */
122 public static void main(String[] args) throws IOException {
123 Scanner scan=new Scanner(System.in);
124 while(scan.hasNext()){
125 LinuxFSTool.executeCommand(scan.nextLine(), System.out,null);
126 }
127
128 }
129}
130
131class ReadThread extends Thread{
132 private InputStream in;//输入流
133 private PrintStream out;
134 private String charset;
135 private JTextArea jta;
136 private boolean flag=true;
137 public void stopThread(){
138 flag=false;
139 }
140 public ReadThread(InputStream in,PrintStream out,String charset) {
141 this.out=out;
142 this.in = in;
143 this.charset=charset;
144 }
145 public ReadThread(InputStream in,PrintStream out,JTextArea jta,String charset) {
146 this.out=out;
147 this.jta=jta;
148 this.in = in;
149 this.charset=charset;
150 }
151 public ReadThread(InputStream in,PrintStream out,JTextArea jta) {
152 this(in, out, jta, "utf-8");
153 }
154 public ReadThread(InputStream in,PrintStream out) {
155 this(in,out,"utf-8");
156
157 }
158 public ReadThread(InputStream in,String charset) {
159 this(in,System.out,charset);
160
161 }
162
163 public ReadThread(InputStream in){
164 this(in, "utf-8");
165 }
166
167 @Override
168 public void run() {
169 BufferedReader br;
170 try {
171 br = new BufferedReader(new InputStreamReader(in,charset));
172
173 String temp;
174
175 while((temp=br.readLine())!=null&&flag==true){
176 // while(br.ready()&&flag==true){//
177 // temp=br.readLine();
178 if(out!=null)
179 { out.println(temp);
180 out.flush();}
181 if(jta!=null){
182 jta.setText(jta.getText()+temp+"\n");
183 }
184 }
185
186 } catch (UnsupportedEncodingException e1) {
187 // TODO Auto-generated catch block
188 e1.printStackTrace();
189 } catch (IOException e) {
190 // TODO Auto-generated catch block
191 e.printStackTrace();
192 }}
193
194}
195 目前本工具存在如下问题:
当输入例如 rm wenjian时 ,由于正常的ssh 会返回是否删除确认,初步分析 由于Ganymed 对返回消息的阻塞,本程序 是否删除某文件显示不出来。只有在下一次命令输入时才返回 是否删除某文件 ?新打入的命令。eclipse项目包,见附件。望大神,大叔,大婶指导。
其余bug 也欢迎指导,本文仅供参考,不足之处多有谅解,转帖请注明地址。
附件下载地址