【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 ...
随机推荐
- EventBus的使用
# EventBus用于android线程间的通信,方便将子线程的数据发送的UI线程,对UI界面更新:总体来说对于这个过程可以分为3个步骤: 1.创建event,用于传递信息: 比如你需要传List集 ...
- 推荐一个自动抽取pdf高亮笔记的web应用
很多人可能像我一样,喜欢用电脑或平板阅读pdf格式的论文或电子书,阅读过程中难免会使用highlight(高亮)工具标记出重要的文字和段落.有没有办法将所有高亮的部分抽取出来,形成一篇单独的笔记呢?下 ...
- 操作系统学习笔记(五)--CPU调度
由于第四章线程的介绍没有上传视频,故之后看书来补. 最近开始学习操作系统原理这门课程,特将学习笔记整理成技术博客的形式发表,希望能给大家的操作系统学习带来帮助.同时盼望大家能对文章评论,大家一起多多交 ...
- Protobuf C#教程 ThriftC#教程大合辑
android与PC,C#与Java 利用protobuf 进行无障碍通讯[Socket] http://www.cnblogs.com/TerryBlog/archive/2011/04/23/20 ...
- Less 语法特性
——(原创翻译:译者添加部分解释和代码运行结果) ♥在线Less编译器:LESS2CSS <一>综述 Less作为CSS的 ...
- Atom 如何隐藏 .Ds_Store 文件
明明在core里设置了忽略文件列表,但是在右侧的文件列表中还是看到了,相当烦人.然后我查了下资料,原来还需要核心插件TreeView再设置一次遵循全局忽略文件才生效. 版本:1.12.6 (其它版本 ...
- VLOOKUP
vlookup(查找目标,查找范围, 返回值的列数,精确或模糊查找) 1. 查找目标:查找的内容或者单元格引用. 2. 查找范围: 选定一个查找区域. 注意一: 查找目标一定要在该区域的第一列. 注意 ...
- ion-refresher 下拉更新数据
使用指令ion-refresher可以为容器eg:ion-scroll 和 ion-content进行拉动刷新 <ion-scroll> <ion-refresher on-refr ...
- ios系统(苹果手机)按钮显示为圆角和渐变的问题
按钮在安卓手机上显示正常,但在苹果手机上会显示如下: 解决办法:给该按钮的样式加上:-webkit-appearance:none;这样按钮就会显示正常
- php +ajax
index.php <html> <head> <meta charset="UTF-8"> <title>Ajax+PHP< ...