【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 server
Session session = jsch.getSession(userName, dstIp, dstPort);
session.setPassword(password);
Properties sshConfig = new Properties();
sshConfig.put("StrictHostKeyChecking", "no");//To skip host-key check
session.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 us
session.setSocketFactory(new SocketFactory() {
@Override
public OutputStream getOutputStream(Socket socket)
throws IOException {
return socket.getOutputStream();
}
@Override
public InputStream getInputStream(Socket socket) throws IOException {
return socket.getInputStream();
}
@Override
public 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 ...
随机推荐
- JAVAWEB学习总结 HTTPSERVLETRESPONSE对象(二)
一.HttpServletResponse常见应用--生成验证码 1.1.生成随机图片用作验证码 生成图片主要用到了一个BufferedImage类 步骤: 1. 在内存中创建一张图片 2.得到图片 ...
- BackTrack5-r3任务栏显示网络图标及自定义DNS
任务栏显示网络连接图标:安装NM工具,在BT终端中执行:apt-get install network-manager按y继续执行,显示:ldconfig deferred processing no ...
- LayaAir引擎——(九)
var h = new Array(); var j = new Array(); var xbCursor = 0; function xbinit() { xbinitName(); xbRect ...
- Chapter 3.GDI/DirectDraw Internal Data Structures
说明,在这里决定跳过第二章,实在是因为里面涉及的内容太理论,对我而言又太艰深 3.1 HANDLES AND OBJECT-ORIRNTED PROGRAMMING In normal object- ...
- 3G数据请求
// 该类负责发送2G/3G Http请求的数据 #import <Foundation/Foundation.h> #import "ASIHTTPRequest.h&quo ...
- DEDECMS 留言薄模块的使用方法
一.留言薄的安装 留言薄的安装过程和其他插件一样,首先我们进入后台模块管理列表,点击其对应的“安装”: 以上步骤,我们完成了留言薄插件的安装. 二.留言薄的卸载 留言薄的卸载,同样首先我们要进入模块管 ...
- java可变参数
Java1.5增加了新特性:可变参数:适用于参数个数不确定,类型确定的情况,java把可变参数当做数组处理.注意:可变参数必须位于最后一项.当可变参数个数多余一个时,必将有一个不是最后一项,所以只支持 ...
- c# 引用百度地图
<script type="text/javascript"> //创建和初始化地图函数 var map = new BMap.Map("home" ...
- JS实现HashMap
/** * ********* 操作实例 ************** * var map = new HashMap(); * map.put("key1","Valu ...
- ios 多种传值方式
在网上看了看传值方法,没有找到完整的.在这把自己看到的几种传值方法写写吧. 1 . 属性传值 2 . 通知传值 3 . 代理传值 4 . block传值 5 . 单列传值 6 . ShareAppli ...