【Jsch】使用SSH协议连接到远程Shell执行脚本

<dependency><groupId>com.jcraft</groupId><artifactId>jsch</artifactId><version>0.1.44</version></dependency>
关键类介绍
- JSch: 作为中心配置点,以及Session的工厂;
This class serves as a central configuration point, and as a factory for Session objects configured with these settings.
- Use getSession to start a new Session.
- Use one of the addIdentity methods for public-key authentication.
- Use setKnownHosts to enable checking of host keys.
- See setConfig for a list of configuration options.
- Session:表示到远程SSH服务器的一个连接,可以包含多个Channels;
A Session represents a connection to a SSH server.One session can contain multiple Channels of various types
- Channel : 与Session相关联的通道,有多种不同类型;
The abstract base class for the different types of channel which may be associated with a Session.
- shell - ChannelShell :A channel connected to a remote shell (本次使用的Channel)
- exec - ChannelExec :A channel connected to a remotely executing program
- direct-tcpip - ChannelDirectTCPIP: A Channel which allows forwarding a pair of local streams to/from a TCP-connection to a server on the remote side
- sftp - ChannelSftp :A Channel connected to an sftp server (as a subsystem of the ssh server).
- subsystem - ChannelSubsystem :A channel connected to a subsystem of the server process
使用步骤
- 步骤1: 使用Jsch获取Session: jsch.getSession()
- 步骤2: 设置Session的password和属性等: setPassword()/setConfig();
- 步骤3: 设置SocketFactory(可以不进行设置,使用默认的TCP socket);
- 步骤4: 打开Session连接:connect();
- 步骤5: 打开并连接Channel:openChannel()/connect();
- 步骤6: 获取Channel的inputStream和outputStream,执行指定cmd或其他;
- getInputStream(): All data arriving in SSH_MSG_CHANNEL_DATA messages from the remote side can be read from this stream
- getOutputStream(): All data written to this stream will be sent in SSH_MSG_CHANNEL_DATA messages to the remote side.
- 步骤7: 关闭各种资源:输入输出流/Session/Channel等;
创建Session,并打开Session连接
使用SSH协议,连接到Linux,执行指定命令,并获取结果
测试程序


完整程序
JSCHUtil.java
package com.sssppp.Communication;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.InetAddress;import java.net.InetSocketAddress;import java.net.Socket;import java.net.UnknownHostException;import java.util.Properties;import com.jcraft.jsch.JSch;import com.jcraft.jsch.JSchException;import com.jcraft.jsch.Session;import com.jcraft.jsch.SocketFactory;/*** 相关链接: JSCH api:http://epaul.github.io/jsch-documentation/javadoc/ Example:* http://www.jcraft.com/jsch/examples/** @author xxxx**/public class JSCHUtil {private static JSch jsch = new JSch();/*** 创建Session,并打开Session连接** @param dstIp* @param dstPort* @param localIp* @param localPort* @param userName* @param password* @param timeOut* @return* @throws JSchException*/public static Session createSession(String dstIp, int dstPort,final String localIp, final int localPort, String userName,String password, final int timeOut) throws JSchException {//jsch.setKnownHosts("/home/foo/.ssh/known_hosts");// A Session represents a connection to a SSH serverSession session = jsch.getSession(userName, dstIp, dstPort);session.setPassword(password);Properties sshConfig = new Properties();sshConfig.put("StrictHostKeyChecking", "no");//To skip host-key checksession.setConfig(sshConfig);// this socket factory is used to create a socket to the target host,// and also create the streams of this socket used by ussession.setSocketFactory(new SocketFactory() {@Overridepublic OutputStream getOutputStream(Socket socket)throws IOException {return socket.getOutputStream();}@Overridepublic InputStream getInputStream(Socket socket) throws IOException {return socket.getInputStream();}@Overridepublic Socket createSocket(String host, int port)throws IOException, UnknownHostException {Socket socket = new Socket();if (localIp != null) {socket.bind(new InetSocketAddress(InetAddress.getByName(localIp), localPort));}socket.connect(new InetSocketAddress(InetAddress.getByName(host), port),timeOut);return socket;}});session.connect(timeOut);return session;}}
SSHCommUtil.java
package com.sssppp.Communication;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import com.jcraft.jsch.Channel;import com.jcraft.jsch.JSchException;import com.jcraft.jsch.Session;public class SSHCommUtil {/*** 测试程序* @param args*/public static void main(String[] args) {String ip = "10.180.137.241";int port = 22;String localIp = null;int localPort = 0;int timeOut = 3000;String userName = "xxx";String password = "xxx";String[] cmds = new String[] { "ifconfig | grep eth0\n","cat /etc/redhat-release\n" };String[] result = null;try {result = execShellCmdBySSH(ip, port, localIp, localPort, timeOut,userName, password, cmds);} catch (Exception e) {e.printStackTrace();}if (result != null) {for (String string : result) {System.out.println(string);System.out.println("-------------------");}}}/*** 使用SSH协议,连接到Linux Shell,执行脚本命令,并获取结果** @param dstIp* @param dstport* default :22* @param localIp* @param localPort* @param timeOut* @param userName* @param password* @param cmds* @return* @throws Exception*/public static String[] execShellCmdBySSH(String dstIp, int dstport,String localIp, int localPort, int timeOut, String userName,String password, String... cmds) throws Exception {Session session = null;Channel channel = null;InputStream is = null;OutputStream os = null;try {session = JSCHUtil.createSession(dstIp, dstport, localIp,localPort, userName, password, timeOut);channel = session.openChannel("shell");// Enable agent-forwarding.// ((ChannelShell)channel).setAgentForwarding(true);// 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();is = channel.getInputStream();os = channel.getOutputStream();String[] result = new String[cmds.length];for (int i = 0; i < cmds.length; i++) {result[i] = sendCommand(is, os, cmds[i]);}return result;} catch (JSchException e) {if (e.getMessage().contains("Auth fail")) {throw new Exception("Auth error");} else {throw new Exception("Connect error");}} catch (Exception e) {throw e;} finally {try {is.close();} catch (IOException e) {}try {os.close();} catch (IOException e) {}channel.disconnect();session.disconnect();}}/*** 执行Shell命令,并获取执行结果** @param is* @param os* @param cmd* @return* @throws IOException*/private static String sendCommand(InputStream is, OutputStream os,String cmd) throws IOException {os.write(cmd.getBytes());os.flush();StringBuffer sb = new StringBuffer();int beat = 0;while (true) {if (beat > 3) {break;}if (is.available() > 0) {byte[] b = new byte[is.available()];is.read(b);sb.append(new String(b));beat = 0;} else {if (sb.length() > 0) {beat++;}try {Thread.sleep(sb.toString().trim().length() == 0 ? 1000: 300);} catch (InterruptedException e) {}}}return sb.toString();}}
【Jsch】使用SSH协议连接到远程Shell执行脚本的更多相关文章
- 【Telnet】使用Telnet协议连接到远程Shell执行脚本
介绍 本文介绍如何通过Telnet协议连接到远程Shell,执行脚本,并获取执行结果: 相关文章: <[Jsch]使用SSH协议连接到远程Shell执行脚本>http://www.cnbl ...
- TortoiseSVN使用svn+ssh协议连接服务器时重复提示输入密码
当使用svn+ssh协议连接svn服务器时,ssh会提示请求认证,由于不是svn客户端程序来完成ssh的认证,所以不会缓存密码. 而svn客户端通常会建立多个版本库的连接,当密码没有缓存的时候,就会重 ...
- linux-ssh远程后台执行脚本-放置后台执行问题(转)
写了一个监控负载的小脚本(死循环,测试结束后再kill对应进程),因需要监控多台服务器,所以在一台服务器上使用ssh统一执行脚本遇到问题:使用ssh root@172.16.146.20 '/usr/ ...
- Findout之为什么公司内部不能使用SSH协议连接外网服务器
今天在公司学习Linux的过程中,想试着像在Windows中操作Github一样对代码进行克隆,只不过是使用命令行的方式.根据一篇博文(Linux下初次使用Github配置)进行了配置,当我进行到第二 ...
- 一步一步学Python(2) 连接多台主机执行脚本
最近在客户现场,每日都需要巡检大量主机系统的备库信息.如果一台台执行,时间浪费的就太冤枉了. 参考同事之前写的一个python脚本,配合各主机上写好的shell检查脚本,实现一次操作得到所有巡检结果. ...
- linux集群自动化搭建(生成密钥对+分发公钥+远程批量执行脚本)
之前介绍过ansible的使用,通过ssh授权批量控制服务器集群 但是生成密钥和分发公钥的时候都是需要确认密码的,这一步也是可以自动化的,利用ssh + expect + scp就可以实现,其实只用这 ...
- shell脚本学习—Shell执行脚本
Shell作用是解释执行用户的命令,用户输入一条命令,Shell就解释执行这一条,这种方式称为交互式,但还有另一种执行命令的方式称为批处理方式,用户事先写一个Shell脚本,Shell可以一次把这些命 ...
- Shell执行脚本
Shell作用是解释执行用户的命令,用户输入一条命令,Shell就解释执行这一条,这种方式称为交互式,但还有另一种执行命令的方式称为批处理方式,用户事先写一个Shell脚本,Shell可以一次把这些命 ...
- 在mac下使用终端命令通过ssh协议连接远程linux系统,代替windows的putty
指令:ssh username@server.address.com 事例:wangmingdeMacBook-Pro:~ xxxxxxxxxx$ ssh root@XXXX.net The auth ...
随机推荐
- Grunt入门教程
引入:grunt是一套前端自动化工具,一个基于nodeJs的命令行工具,一般用于: ① 压缩文件 ② 合并文件 ③ 简单语法检查 环境:grunt是基于nodejs运行的,所以需要有nodejs,在N ...
- Android studio快捷键大全 和 eclipse对照(原)
Ctrl+空格 代码提示 (同Eclipse中Alt+/) Ctrl+Shjft+N 项目 ...
- Mercurial笔记(hg命令)
两个站点: http://z42.readthedocs.org/zh/latest/devtools/hg.html http://bucunzai.net/hginit/ 添加用户名 在.hg目录 ...
- 前端二:CSS
CSS: 一:介绍:学名层叠样式表(Cading Style Sheets)是一种用来表现HTML或者XML等文件的样式的计算机语言.让HTML和XML看起来更加美观. 语法:<style> ...
- 修复Windows XP右键没有新建菜单问题
桌边上,点击鼠标右键,也没有排列图标菜单 开始-运行-输入:cmd输入命令:reg add "HKEY_CLASSES_ROOT\Directory\Background\shellex\C ...
- cs231n笔记:最优化
本节是cs231学习笔记:最优化,并介绍了梯度下降方法,然后应用到逻辑回归中 引言 在上一节线性分类器中提到,分类方法主要有两部分组成:1.基于参数的评分函数.能够将样本映射到类别的分值.2.损失函数 ...
- android 手机屏幕有关的几个工具(屏幕宽高,dp和px互相转换)
平时适配页面时经常会需要根据屏幕的宽高来设置控件的大小,很多时候在代码中还会需要dp和px互相转换. 今天把最常用的几个记录一下,经测试包括2.3 ~ 5.0之间的版本都可用,其他版本未测,不过应该也 ...
- Pixel VS Point, FrameBuffer VS RenderBuffer
// How iOS app MVC works View, Window, AppDelegate ViewController, RootViewController // On Pixel VS ...
- vector使用篇之erase
由于最近项目使用中发现了之前对vector的一个误区,由此发现自己对vect非常不了解,对此进行了一些了解,由此打算写一下关于vector使用方面的注意点,本篇先来讲一下vector的erase功能, ...
- 关于<head></head>标签;<form></form>标签
<head> <title>此处写标题</title> 这是唯一能被用户看到的标记 <meta/>标签: 1.设置字符集:<meta http-e ...