JSch基本使用
JSch基本使用
JSch 是SSH2的一个纯Java实现。它允许你连接到一个sshd 服务器,使用端口转发,X11转发,文件传输等等。你可以将它的功能集成到你自己的 程序中。同时该项目也提供一个J2ME版本用来在手机上直连SSHD服务器。
官网:http://www.jcraft.com/jsch/中有很多例子http://www.jcraft.com/jsch/examples/,这里先采用(已做修改)其中2个来进行简单论述,希望对大家有所帮助。
本文采用的jsch版本是0.1.51. 下载地址:http://sourceforge.net/projects/jsch/files/jsch/0.1.54/jsch-0.1.54.zip/download。
本文采用的Linux操作系统是CentOS6.5.
TIPS: 查看Linux操作系统(内核)版本可以使用:uname -a; uname -r; cat /etc/issue; cat /etc/redhat-release等命令。
第一个例子:采用Java模拟shell操作。
这里涉及到几个参数,会在下面的代码中有所体现:
- USER:所连接的Linux主机登录时的用户名
- PASSWORD:登录密码
- HOST:主机地址
- DEFAULT_SSH_PROT=端口号,默认为22
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
package com.test.jsch;/** * This program enables you to connect to sshd server and get the shell prompt. * You will be asked username, hostname and passwd. * If everything works fine, you will get the shell prompt. Output may * be ugly because of lacks of terminal-emulation, but you can issue commands. */import com.jcraft.jsch.JSch;import com.jcraft.jsch.Session;import com.jcraft.jsch.UserInfo;import com.jcraft.jsch.Channel;public class Shell{ private static final String USER="root"; private static final String PASSWORD="********"; private static final String HOST="localhost"; private static final int DEFAULT_SSH_PORT=22; public static void main(String[] arg){ try{ JSch jsch=new JSch(); Session session = jsch.getSession(USER,HOST,DEFAULT_SSH_PORT); session.setPassword(PASSWORD); UserInfo userInfo = new UserInfo() { @Override public String getPassphrase() { System.out.println("getPassphrase"); return null; } @Override public String getPassword() { System.out.println("getPassword"); return null; } @Override public boolean promptPassword(String s) { System.out.println("promptPassword:"+s); return false; } @Override public boolean promptPassphrase(String s) { System.out.println("promptPassphrase:"+s); return false; } @Override public boolean promptYesNo(String s) { System.out.println("promptYesNo:"+s); return true;//notice here! } @Override public void showMessage(String s) { System.out.println("showMessage:"+s); } }; session.setUserInfo(userInfo); // It must not be recommended, but if you want to skip host-key check, // invoke following, // session.setConfig("StrictHostKeyChecking", "no"); //session.connect(); session.connect(30000); // making a connection with timeout. Channel channel=session.openChannel("shell"); // Enable agent-forwarding. //((ChannelShell)channel).setAgentForwarding(true); channel.setInputStream(System.in); /* // a hack for MS-DOS prompt on Windows. channel.setInputStream(new FilterInputStream(System.in){ public int read(byte[] b, int off, int len)throws IOException{ return in.read(b, off, (len>1024?1024:len)); } }); */ channel.setOutputStream(System.out); /* // Choose the pty-type "vt102". ((ChannelShell)channel).setPtyType("vt102"); */ /* // Set environment variable "LANG" as "ja_JP.eucJP". ((ChannelShell)channel).setEnv("LANG", "ja_JP.eucJP"); */ //channel.connect(); channel.connect(3*1000); } catch(Exception e){ System.out.println(e); } }} |
运行结果:
|
1
2
3
4
5
6
|
promptYesNo:The authenticity of host '10.101.139.5' can't be established.RSA key fingerprint is 59:0f:32:fc:7b:54:3d:90:c0:ef:5a:6b:fb:11:55:e1.Are you sure you want to continue connecting?trueLast login: Thu Sep 29 18:40:56 2016 from 10.101.48.240[root@hidden ~]# |
输入ls查看:
|
1
2
3
4
5
6
7
|
(省略一些....)[root@hidden ~]# lsls1.txt install.log.syslog vmware-tools-distrib 模板 文档 桌面anaconda-ks.cfg logs workspace 视频 下载install.log util 公共的 图片 音乐[root@hidden ~]# |
这样就和在原linux系统中一样使用shell功能了。
如果需要跳过如下的检测:
|
1
2
3
|
The authenticity of host '10.101.139.5' can't be established.RSA key fingerprint is 59:0f:32:fc:7b:54:3d:90:c0:ef:5a:6b:fb:11:55:e1.Are you sure you want to continue connecting? |
只需要在程序中加入相应的代码:
|
1
|
session.setConfig("StrictHostKeyChecking", "no"); |
运行结果:
|
1
2
|
Last login: Thu Sep 29 18:39:18 2016 from 10.101.48.240[root@hidden ~]# |
第二个例子:运行一条shell指令,这里就那“ls”做例子好了。
No more talk, show you the code:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
package com.test.jsch;import com.jcraft.jsch.*;import java.io.*;public class Exec{ private static final String USER="root"; private static final String PASSWORD="********"; private static final String HOST="localhost"; private static final int DEFAULT_SSH_PORT=22; public static void main(String[] arg){ try{ JSch jsch=new JSch(); Session session = jsch.getSession(USER,HOST,DEFAULT_SSH_PORT); session.setPassword(PASSWORD); // username and password will be given via UserInfo interface. session.setUserInfo(new MyUserInfo()); session.connect(); String command="ls"; Channel channel=session.openChannel("exec"); ((ChannelExec)channel).setCommand(command); // X Forwarding // channel.setXForwarding(true); //channel.setInputStream(System.in); channel.setInputStream(null); //channel.setOutputStream(System.out); //FileOutputStream fos=new FileOutputStream("/tmp/stderr"); //((ChannelExec)channel).setErrStream(fos); ((ChannelExec)channel).setErrStream(System.err); InputStream in=channel.getInputStream(); channel.connect(); byte[] tmp=new byte[1024]; while(true){ while(in.available()>0){ int i=in.read(tmp, 0, 1024); if(i<0)break; System.out.print(new String(tmp, 0, i)); } if(channel.isClosed()){ if(in.available()>0) continue; System.out.println("exit-status: "+channel.getExitStatus()); break; } try{Thread.sleep(1000);}catch(Exception ee){} } channel.disconnect(); session.disconnect(); } catch(Exception e){ System.out.println(e); } } private static class MyUserInfo implements UserInfo{ @Override public String getPassphrase() { System.out.println("getPassphrase"); return null; } @Override public String getPassword() { System.out.println("getPassword"); return null; } @Override public boolean promptPassword(String s) { System.out.println("promptPassword:"+s); return false; } @Override public boolean promptPassphrase(String s) { System.out.println("promptPassphrase:"+s); return false; } @Override public boolean promptYesNo(String s) { System.out.println("promptYesNo:"+s); return true;//notice here! } @Override public void showMessage(String s) { System.out.println("showMessage:"+s); } }} |
运行结果:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
promptYesNo:The authenticity of host '10.101.139.5' can't be established.RSA key fingerprint is 59:0f:32:fc:7b:54:3d:90:c0:ef:5a:6b:fb:11:55:e1.Are you sure you want to continue connecting?1.txtanaconda-ks.cfginstall.loginstall.log.sysloglogsutilvmware-tools-distribworkspace公共的模板视频图片文档下载音乐桌面exit-status: 0 |
第二个例子相比于第一个例子来说将UserInfo采用static class的方式提取出来,这样更直观一点。
JSch是以多线程方式一下,所以代码在connect后如果不disconnect channel和session,以及相关stream, 程序会一直等待,直到关闭。
需要注意的一个问题,相关的Stream和Channel是一定要关闭的,那么应该在什么时候来关?执行connect后,JSch接受客户端结果需要一定的时间(以秒计),如果马上关闭session就会发现什么都没接受到或内容不全。
还有一点注意,使用shell时,看到执行后没有结果,解决办法是在命令行后加上”\n”字符,server端就认为是一条完整的命令了。
最后将第一个和第二个例子合并,并提取一些公用模块,以便更好的理解和使用:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
package com.test.jsch;import com.jcraft.jsch.*;import java.io.*;import java.util.concurrent.TimeUnit;import static java.lang.String.format;/** * Created by hidden on 2016/9/29. */public class SSHExecutor { private static long INTERVAL = 100L; private static int SESSION_TIMEOUT = 30000; private static int CHANNEL_TIMEOUT = 3000; private JSch jsch = null; private Session session = null; private SSHExecutor(SSHInfo sshInfo) throws JSchException { jsch =new JSch(); session = jsch.getSession(sshInfo.getUser(),sshInfo.getHost(),sshInfo.getPort()); session.setPassword(sshInfo.getPassword()); session.setUserInfo(new MyUserInfo()); session.connect(SESSION_TIMEOUT); } /* * 在这里修改访问入口,当然可以把这个方法弄到SSHExecutor外面,这里是方便操作才这么做的 * */ public static SSHExecutor newInstance() throws JSchException { SSHInfo sshInfo = new SSHInfo("root","******","locahost",22); return new SSHExecutor(sshInfo); } /* * 注意编码转换 * */ public long shell(String cmd, String outputFileName) throws JSchException, IOException, InterruptedException { long start = System.currentTimeMillis(); Channel channel = session.openChannel("shell"); PipedInputStream pipeIn = new PipedInputStream(); PipedOutputStream pipeOut = new PipedOutputStream( pipeIn ); FileOutputStream fileOut = new FileOutputStream( outputFileName, true); channel.setInputStream(pipeIn); channel.setOutputStream(fileOut); channel.connect(CHANNEL_TIMEOUT); pipeOut.write(cmd.getBytes()); Thread.sleep( INTERVAL ); pipeOut.close(); pipeIn.close(); fileOut.close(); channel.disconnect(); return System.currentTimeMillis() - start; } public int exec(String cmd) throws IOException, JSchException, InterruptedException { ChannelExec channelExec = (ChannelExec)session.openChannel( "exec" ); channelExec.setCommand( cmd ); channelExec.setInputStream( null ); channelExec.setErrStream( System.err ); InputStream in = channelExec.getInputStream(); channelExec.connect(); int res = -1; StringBuffer buf = new StringBuffer( 1024 ); byte[] tmp = new byte[ 1024 ]; while ( true ) { while ( in.available() > 0 ) { int i = in.read( tmp, 0, 1024 ); if ( i < 0 ) break; buf.append( new String( tmp, 0, i ) ); } if ( channelExec.isClosed() ) { res = channelExec.getExitStatus(); System.out.println( format( "Exit-status: %d", res ) ); break; } TimeUnit.MILLISECONDS.sleep(100); } System.out.println( buf.toString() ); channelExec.disconnect(); return res; } public Session getSession(){ return session; } public void close(){ getSession().disconnect(); } /* * SSH连接信息 * */ public static class SSHInfo{ private String user; private String password; private String host; private int port; public SSHInfo(String user, String password, String host, int port) { this.user = user; this.password = password; this.host = host; this.port = port; } public String getUser() { return user; } public String getPassword() { return password; } public String getHost() { return host; } public int getPort() { return port; } } /* * 自定义UserInfo * */ private static class MyUserInfo implements UserInfo{ @Override public String getPassphrase() { return null; } @Override public String getPassword() { return null; } @Override public boolean promptPassword(String s) { return false; } @Override public boolean promptPassphrase(String s) { return false; } @Override public boolean promptYesNo(String s) { System.out.println(s); System.out.println("true"); return true; } @Override public void showMessage(String s) { } }} |
测试代码:
|
1
2
3
4
5
6
7
8
9
|
SSHExecutor ssh = SSHExecutor.newInstance();System.out.println("================");long shell1 = ssh.shell("ls\n","C:\\Users\\hidden\\Desktop\\shell.txt");long shell2 = ssh.shell("pwd\n","C:\\Users\\hidden\\Desktop\\shell.txt");System.out.println("shell 1 执行了"+shell1+"ms");System.out.println("shell 2 执行了"+shell2+"ms");System.out.println("================");int cmd1 = ssh.exec("ls\n");ssh.close(); |
测试结果:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
The authenticity of host '10.101.139.5' can't be established.RSA key fingerprint is 59:0f:32:fc:7b:54:3d:90:c0:ef:5a:6b:fb:11:55:e1.Are you sure you want to continue connecting?true================shell 1 执行了142msshell 2 执行了132ms================Exit-status: 01.txtanaconda-ks.cfginstall.loginstall.log.sysloglogsutilvmware-tools-distribworkspace公共的模板视频图片文档下载音乐桌面 |
还有解释查看一下左边是否有个shell.txt以及shell.txt是否有相应的内容。
JSch基本使用的更多相关文章
- 通过JSch编写上传、下载文件
package com.hct.util; /** * @作者: HCT * @时间:2016年12月29日下午3:13:20 * @描述: * */ import java.io.*; import ...
- JSCH通过密钥文件进行远程访问
需求:WEB app 需要使用JSCH来通过密钥文件的方式进行SFTP/SSH访问远程LINUX机器 实现方式:假设远程机器都含有用户名为hadoop的用户,因为密码因为策略的要求密码会随时间发生变化 ...
- 【SFTP】使用Jsch实现Sftp文件下载-支持断点续传和进程监控
参考上篇文章: <[SFTP]使用Jsch实现Sftp文件下载-支持断点续传和进程监控>:http://www.cnblogs.com/ssslinppp/p/6248763.html ...
- 【SFTP】使用Jsch实现Sftp文件上传-支持断点续传和进程监控
JSch是Java Secure Channel的缩写.JSch是一个SSH2的纯Java实现.它允许你连接到一个SSH服务器,并且可以使用端口转发,X11转发,文件传输等,当然你也可以集成它的功能到 ...
- 【转】JSch - Java实现的SFTP(文件下载详解篇)
上一篇讲述了使用JSch实现文件上传的功能,这一篇主要讲述一下JSch实现文件下载的功能.并介绍一些SFTP的辅助方法,如cd,ls等. 同样,JSch的文件下载也支持三种传输模式:OVERWRI ...
- 【转】JSch - Java实现的SFTP(文件上传详解篇)
JSch是Java Secure Channel的缩写.JSch是一个SSH2的纯Java实现.它允许你连接到一个SSH服务器,并且可以使用端口转发,X11转发,文件传输等,当然你也可以集成它的功能到 ...
- 【Jsch】使用SSH协议连接到远程Shell执行脚本
如果大家熟悉Linux的话,一定对ssh,sftp,scp等命令非常熟悉,ssh是一个安全协议,用来在不同系统或者服务器之间进行安全连接,SSH 在连接和传送的过程中会加密所有的数据. 但是SSH一般 ...
- java使用jsch连接linux
由于项目需要使用java来linux进行管理,近一番查找,发现第三方jar包 jsch 可以轻松实现对linux的管理,(相关文档及例子请访问官网www.jcraft.com),故引进. 在网上搜索了 ...
- 基于JSch的Sftp工具类
本Sftp工具类的API如下所示. 1)构造方法摘要 Sftp(String host, int port, int timeout, String username, String password ...
- JSch - Java实现的SFTP(文件下载详解篇)
上一篇讲述了使用JSch实现文件上传的功能,这一篇主要讲述一下JSch实现文件下载的功能.并介绍一些SFTP的辅助方法,如cd,ls等. 同样,JSch的文件下载也支持三种传输模式:OVERWRITE ...
随机推荐
- Jquery EasyUI Tree树形结构的Java实现(实体转换VO)
前一阵做的OA项目,有一个是组织架构的树,因为是分开做的,我做的是Controller和页面,其他组做的Service和Dao,因为之前一直没有商量页面用什么框架做比较好,导致,Dao层取出来的数据都 ...
- python decorator 装饰器
python装饰器是个对嵌套函数的语法糖 作用是在函数调用方法不变的情况下,将函数包装成另一个函数来使用 ---- import time def sum1(): sum = 1 + 2 print ...
- 一张图说明HTTPS 握手过程
- XOR Queries(莫队+trie)
题目链接: XOR Queries 给出一个长度为nn的数组CC,回答mm个形式为(L, R, A, B)(L,R,A,B)的询问,含义为存在多少个不同的数组下标k \in [L, R]k∈[L,R] ...
- img 在chrome和Firefox下的兼容性
Firefox 5.下:没有重叠在一起: chrome 下: 两个重叠在一起, 原因: img标签,在两个浏览器下展示效果不一样, 解决办法:指明展示:
- CuratorFramework入门指南
CuratorFramework入门指南 原文地址:https://github.com/Netflix/curator/wiki/Getting-Started CuratorFramework作为 ...
- Android Bluetooth 总结
一.Android Bluetooth现状 (1)Android2.2版 支持的蓝牙核心版本是Bluetooth 2.0 + EDR. (2)Android 的蓝牙 使用了BlueZ协议栈,但只实现了 ...
- 【剑指offer】包含min函数的栈,C++实现
博客文章索引地址 博客文章中代码的github地址 1.题目 定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数.在该栈中调用push.pop.top.min的时间复杂度都是o(1) ...
- 【剑指offer】10矩阵覆盖
原创博文,转载请注明出处! 0.简介 # 本文是牛客网<剑指offer>刷题笔记,笔记索引链接 1.题目 # 用2*1的小矩形横着或者竖着去覆盖更大的矩形.请问用n个2*1的小矩形无重叠地 ...
- eclipse 无用代码扫描工具UCDetector
本文主要介绍UCDetector(无用代码扫描工具)使用方法及局限 对于沉积或多方接手开发的项目经常会遇到一坨一坨无用的代码,但一个一个类查找又相当费时,这里介绍一个eclipse插件扫描没有引用的类 ...