JSch:Java Secure Channel -- java 代码实现 ssh 远程操作

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。

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 ~]# ls
ls
1.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.txt
anaconda-ks.cfg
install.log
install.log.syslog
logs
util
vmware-tools-distrib
workspace
公共的
模板
视频
图片
文档
下载
音乐
桌面
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 执行了142ms
shell 2 执行了132ms
================
Exit-status: 0
1.txt
anaconda-ks.cfg
install.log
install.log.syslog
logs
util
vmware-tools-distrib
workspace
公共的
模板
视频
图片
文档
下载
音乐
桌面

还有解释查看一下左边是否有个shell.txt以及shell.txt是否有相应的内容。

 

 

转自:http://www.importnew.com/22322.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/449341.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

国信证券学习系列(3)

日内回转策略&#xff1a;做T策略 择时交易&#xff1a; if date[-8:-3] ! 14:55:if macd > 0 and macd_pre < 0:# 根据MACD>0则开仓,小于0则平仓if avaliable > df.iloc[-1, 0] * ContextInfo.Lots * 100:order_shares(ContextInfo.get_universe()[0], ContextIn…

时序数据库连载系列: 时序数据库一哥InfluxDB之存储机制解析

2019独角兽企业重金招聘Python工程师标准>>> InfluxDB 的存储机制解析 本文介绍了InfluxDB对于时序数据的存储/索引的设计。由于InfluxDB的集群版已在0.12版就不再开源&#xff0c;因此如无特殊说明&#xff0c;本文的介绍对象都是指 InfluxDB 单机版 1. InfluxDB 的…

如何在Linux上提高文本的搜索效率

本文由 极客范 - minejo 翻译自 Xmodulo。欢迎加入极客翻译小组&#xff0c;同我们一道翻译与分享。转载请参见文章末尾处的要求。对于系统管理员或程序员来说&#xff0c;当需要在复杂配置的目录中或者在大型源码树中搜寻特定的文本或模式时&#xff0c;grep类型的工具大概是…

Spring Boot 10:处理Json数据中的null值

Jackson版&#xff1a; /*** Jackson 配置类 对Json数据进行特殊处理** Author YangXuyue* Date 2019/04/02 07:12*/ Configuration public class JacksonConfig {/*** 配置Jackson** param builder* return* Author YangXuyue* Date 2019/04/02 07:14*/BeanPrimaryConditional…

国信证券学习系列(4)

机器学习篇章&#xff0c;本章不过时脚本小子&#xff0c;机器学习最核心的是机器&#xff0c;是模型。 学习&#xff0c;无非就是找些有的没的因子扔进去&#xff0c;但说实话&#xff0c;机器学习&#xff0c;太过容易过拟合&#xff0c;容易无效化。回测好看的一笔&#xf…

JSch - Java Secure Channel : java 代码实现服务器远程操作

一、前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 JSch是SSH2的纯Java实现 。 JSch允许您连接到sshd服务器并使用端口转发&#xff0c;X11转发&#xff0c;文件传输等&#xff0…

前嗅ForeSpider教程:数据建表

今天&#xff0c;小编为大家带来的教程是&#xff1a;如何在前嗅ForeSpider中&#xff0c;进行数据建表操作及各注意事项。主要内容包括&#xff1a;快速建表&#xff0c;自由建表&#xff0c;字段参数&#xff0c;数据表的创建&#xff0c;关联与删除&#xff0c;以及表单变更…

世纪大争论:Linux还是GNU/Linux?

本文由 极客范 - 爱开源的贡献开源社区 翻译自 Chris Hoffman。欢迎加入极客翻译小组&#xff0c;同我们一道翻译与分享。转载请参见文章末尾处的要求。我们在网上已经习惯用“Linux”来称呼Linux操作系统了&#xff0c;然而&#xff0c;偶尔也用“GNU/Linux”来称呼和指代同…

PyTorch Softmax

PyTorch provides 2 kinds of Softmax class. The one is applying softmax along a certain dimension. The other is do softmax on a spatial matrix sized in B, C, H, W. But it seems like some problems existing in Softmax2d. : ( 转载于:https://www.cnblogs.com/hiz…

国信证券学习系列(5)

网格策略&#xff0c;号称胜率100%的策略&#xff0c;只要扛得住回撤&#xff0c;怎么说呢&#xff0c;它包含了最简单的思想&#xff0c;大道至简&#xff0c;真的是没有什么复杂的&#xff0c;原理清晰&#xff0c;思路简单。可以明确知道我挣的是那笔钱&#xff0c;为什么获…

promise

## 前言 今天来分享下promise的用法&#xff0c;es6伟大发明之一&#xff0c;当初我学习的时候也是蛮头大的&#xff0c;不知道为啥&#xff0c;整个脑子就是&#xff0c;我在哪&#xff0c;我要干啥的懵圈&#xff0c;后面认真学习之后&#xff0c;觉得真是十分好用&#xff0…

计算机集群 解说

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 计算机集群简称集群是一种计算机系统&#xff0c;它通过一组松散集成的计算机软件和/或硬件连接起来高度紧密地协作完成计算工作。 在某…

同时寻找最大数和最小数的最优算法 第二大数

我们知道&#xff0c;在一个容量为n的数据集合中寻找一个最大数&#xff0c;不管用什么样的比较算法&#xff0c;至少要比较n-1次&#xff0c;就算是用竞标赛排序也得比较n-1次&#xff0c;否则你找到的就不能保证是最大的数。那么&#xff0c;在一个容量为n的数据集合中同时寻…

浅谈mpvue项目目录和文件结构

2019独角兽企业重金招聘Python工程师标准>>> 在Visual Studio Code里面打开项目文件夹&#xff0c;我们可以看到类似如下的文件结构&#xff1a; 1、package.json文件 package.json是项目的主配置文件&#xff0c;里面包含了mpvue项目的基本描述信息、项目所依赖的各…

[AHOI2009]最小割(最大流+tarjan)

继续填坑了&#xff0c;啦啦啦 这道题本来是准备枚举每个边&#xff0c;暂时去除它&#xff0c;但发现时间会爆炸的 于是决定另辟蹊径 于是这篇题解就应运而生 首先还是网络流跑一边 毕竟题目叫最小割嘛&#xff0c;给个面子 然后跑一边tarjan对满流的边处理掉&#xff0c;即不…

进程间通信---信号

什么是信号&#xff1f; 】 信号处理流程 信号类型 发送信号的函数 参数sig&#xff1a;代表 信号 接收信号的函数 参数 handle 的处理方式有几种&#xff1f; 实例代码 实例逻辑 图中的等待操作使用&#xff1a;pause&#xff08;&#xff09;函数 代码 在这里插入代码片…

大白话解说,半分钟就懂 --- 分布式与集群是什么 ? 区别是什么?

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 PS&#xff1a;这篇文章算是笔记&#xff0c;仅部分文字是原创&#xff0c;相当内容只是收集、整理、提炼、总结别人写的。 没有标为原创…

国信证券学习系列(6)

行业轮动策略&#xff1a; 本策略每隔1个月定时触发计算1000能源&#xff08;399381.SZ&#xff09;、1000材料&#xff08;399382.SZ&#xff09;、1000工业&#xff08;399383.SZ&#xff09;、1000可选&#xff08;399384.SZ&#xff09;、1000消费&#xff08;399385.SZ&a…

用Linux命令行修图——缩放、编辑、转换格式——一切皆有可能

本文由 极客范 - 八卦爱好者 翻译自 How-To Geek。欢迎加入极客翻译小组&#xff0c;同我们一道翻译与分享。转载请参见文章末尾处的要求。ImageMagick是一系列的用于修改、加工图像的命令行工具。ImageMagick能够快速地使用命令行对图片进行操作&#xff0c;对大量的图片进行…

剑指offer:二维数组中的查找

目录 题目解题思路具体代码题目 题目链接剑指offer&#xff1a;二维数组中的查找题目描述 在一个二维数组中&#xff08;每个一维数组的长度相同&#xff09;&#xff0c;每一行都按照从左到右递增的顺序排序&#xff0c;每一列都按照从上到下递增的顺序排序。请完成一个函数&a…