如何用java程序(JSch)运行远程linux主机上的shell脚本
作者:字母哥博客 发布时间:2023-11-24 12:35:58
标签:JAVA,JSCH,Linux,shell,脚本
运行远程主机上的shell脚本
下面的例子是教给大家如何通过java程序,运行远程主机上的shell脚本。(我讲的不是一个黑客学习教程,而是使用用户名密码去执行有用户认证资格的主机上的shell脚本)。并且通过java程序获得shell脚本的输出。
首先通过maven坐标引入JSch依赖库,我们正是通过JSch去执行远程主机上的脚本。
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
当然以下java代码可执行的的前提是,远程主机已经开通SSH服务(也就是我们平时登录主机所使用的服务)。
远程shell脚本
下面的代码放入一个文件:hello.sh,脚本的内容很简单只是用来测试,回显输出“hello <参数1> ”
#! /bin/sh
echo "hello $1\n";
然后我把它放到远程主机的/root目录下面,远程主机的IP是1.1.1.1(当然我真实测试时候不是这个IP,我不能把我的真实IP写到这个文章里面,以免被攻击)。并且在远程主机上,为这个脚本设置可执行权限,方法如下:
$ chmod +x hello.sh
本地java程序
我们可以使用下面的代码,去远程的linux 主机执行shell脚本,详细功能请看代码注释
import com.jcraft.jsch.*;
import java.io.IOException;
import java.io.InputStream;
public class RunRemoteScript {
//远程主机IP
private static final String REMOTE_HOST = "1.1.1.1";
//远程主机用户名
private static final String USERNAME = "";
//远程主机密码
private static final String PASSWORD = "";
//SSH服务端口
private static final int REMOTE_PORT = 22;
//会话超时时间
private static final int SESSION_TIMEOUT = 10000;
//管道流超时时间(执行脚本超时时间)
private static final int CHANNEL_TIMEOUT = 5000;
public static void main(String[] args) {
//脚本名称及路径,与上文要对上
String remoteShellScript = "/root/hello.sh";
Session jschSession = null;
try {
JSch jsch = new JSch();
//SSH授信客户端文件位置,一般是用户主目录下的.ssh/known_hosts
jsch.setKnownHosts("/home/zimug/.ssh/known_hosts");
jschSession = jsch.getSession(USERNAME, REMOTE_HOST, REMOTE_PORT);
// 密码认证
jschSession.setPassword(PASSWORD);
// 建立session
jschSession.connect(SESSION_TIMEOUT);
//建立可执行管道
ChannelExec channelExec = (ChannelExec) jschSession.openChannel("exec");
// 执行脚本命令"sh /root/hello.sh zimug"
channelExec.setCommand("sh " + remoteShellScript + " zimug");
// 获取执行脚本可能出现的错误日志
channelExec.setErrStream(System.err);
//脚本执行结果输出,对于程序来说是输入流
InputStream in = channelExec.getInputStream();
// 5 秒执行管道超时
channelExec.connect(CHANNEL_TIMEOUT);
// 从远程主机读取输入流,获得脚本执行结果
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 (channelExec.isClosed()) {
if (in.available() > 0) continue;
//获取退出状态,状态0表示脚本被正确执行
System.out.println("exit-status: "
+ channelExec.getExitStatus());
break;
}
try {
Thread.sleep(1000);
} catch (Exception ee) {
}
}
channelExec.disconnect();
} catch (JSchException | IOException e) {
e.printStackTrace();
} finally {
if (jschSession != null) {
jschSession.disconnect();
}
}
}
}
最终在本地控制台,获得远程主机上shell脚本的执行结果。如下
hello zimug
exit-status: 0
当然,我只是为大家演示这样一个例子,上面的代码可以通过更好的封装,从而提供更简单的使用方式。
来源:https://www.cnblogs.com/zimug/archive/2020/08/07/13450493.html


猜你喜欢
- 本人使用小米手机,打开qq或者微信的时候,某个权限拒绝的话,会提示你开启,点击开启会跳转到app的权限设置界面,当然了,这是国内系统深层定制
- 对于简单的场景来讲,在MEF中导入依赖模块非常简单,只要用ImportAttribute标记依赖的成员,MEF模块会自动找到并创建该模块。但
- 背景今天学习Springboot,但是用的apache-maven 3.0 ,导入springboot1.5.19 ,Maven项目老是爆红
- bean作用域bean的作用域,其实就是设置创建 bean 的实例是属于单实例,还是多实例。1. 默认单实例默认情况下,创建的 bean 是
- Object是类层次结构的根,每个类都可以将Object作为超类。所有类都直接或者间接的继承自该类构造方法:public Object()回
- 查 看: File------>Project Structure-------
- 一.先说结论针对任何一个代码记录都进行Revert Commit操作:①不管此记录是commit未push,还是已经push过;②不管此记录
- 本篇文章依旧采用小例子来说明,因为我始终觉的,案例驱动是最好的,要不然只看理论的话,看了也不懂,不过建议大家在看完文章之后,在回过头去看看理
- 本文实例为大家分享了Android实现ListView下拉刷新上拉加载更多的具体代码,供大家参考,具体内容如下其实谷歌官方目前已经推出Lis
- 定时任务1import lombok.extern.slf4j.Slf4j;/** * @author Created by niugang
- 最近学习了一下seata,由于nacos现在也挺火,于是学习了seata注册到nacos,然后集成springcloud1.nacos配置(
- 1.项目介绍本项目旨在打造一个基于RBAC架构模式的通用的、并不复杂但易用的权限管理系统。通过本项目可以较好的理解权限系统的常见业务同时学习
- 本文介绍在C#窗体编程时,如何设置不显示右上角的最小化最大化关闭按钮。可以通过this.ControlBox这个属性的值来控制。在Windo
- 1、return语句的作用:a、返回一个值,这个值可以是任意类型。b、使程序返回到操作系统(即终止程序)2、java中对于一个函数,不论有没
- 当一个activity中含有输入框时,我们点击输入框,会弹出输入法界面,整个界面的变化效果与manifest中对应设置的andr
- 1.1 概述分布式系统:分布式系统指由很多台计算机组成的一个整体!这个整体一致对外,并且处理同一请求!系统对内透明,对外不透明!内部的每台计
- 引子public class InheritableThreadLocalDemo { private stati
- 一、材料准备1、jdk1.8的安装包2、maven安装包3、idea工具二、配置jdk1.8环境变量1.jdk下载jdk下载网址(点击此链接
- 使用SwingWorker线程模式谨慎地使用并发机制对Swing开发人员来说非常重要。一个好的Swing程序使用并发机制来创建不会失去响应的
- 一、单文件压缩 场景,文件可能比较大,需要压缩传输,比如上传和下载/// <summary&g