简单的java调动远程服务器shell脚本
1.需求
我们想要在我们的xxl-job
中调用一个定时任务,固定时间频率去调用另一个服务器的shell
脚本,进行数据批量的处理,整体需求逻辑非常简单,此处记录一下java调用shell脚本部分,方便之后开发复习使用,xxl-job
部分的配置此处就不多赘述了,此文主要记录调用shell部分逻辑。
2.具体实现
java中,我们可以使用JSch
库来远程登录服务器并执行shell脚本即可,整体的逻辑也非常简单,具体实现步骤如下:
-
准备执行脚本
此处我们是测试脚本,随便编写一个测试脚本即可,我们在服务器创建一个test.sh
的脚本,里面输出test ok
# 创建目录文件 mkdir /root/shell cd /root/shell # 其中shell脚本中只有 echo "test ok!" vim test.sh # 添加执行权限 chmod +x test.sh
-
引入工具类maven坐标
<!-- 远程执行shell --><dependency><groupId>com.jcraft</groupId><artifactId>jsch</artifactId><version>0.1.55</version></dependency>
-
编写调用工具类
package cn.git.controller;import cn.hutool.core.util.StrUtil; import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelExec; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.io.InputStream;/*** 控制器用于远程执行shell脚本。** @program: bank-credit-sy* @author: lixuchun* @create: 2024-05-03*/ @RestController @RequestMapping("/shell") public class ExecShellController {/*** 日志记录器*/private static final Logger logger = LoggerFactory.getLogger(ExecShellController.class);/*** 测试远程执行shell脚本的方法。** @return 返回执行结果的信息*/@RequestMapping("/exec")public String test() {// 定义远程服务器的登录信息,用户名称String user = "root";// 密码String password = "101022li";// 地址String host = "192.168.138.129";int port = 22; // 端口try {JSch jsch = new JSch();Session session = jsch.getSession(user, host, port);session.setPassword(password);// 设置配置避免首次连接时的确认提示session.setConfig("StrictHostKeyChecking", "no");// 建立连接,设定超时时间5ssession.connect(5000);// 准备执行的shell命令String execCommand = "sh /root/shell/test.sh";Channel channel = session.openChannel("exec");((ChannelExec) channel).setCommand(execCommand);// 不向远程服务器发送输入channel.setInputStream(null);// 将错误输出流重定向到标准错误输出((ChannelExec) channel).setErrStream(System.err);// 连接通道,设置超时时间为1s,单位为毫秒channel.connect(5000);// 读取shell脚本的标准输出StringBuilder result = new StringBuilder(StrUtil.EMPTY);try (InputStream in = channel.getInputStream()) {byte[] buffer = new byte[1024]; // 缓冲区大小int readCount;// 循环读取直到没有更多数据while ((readCount = in.read(buffer)) > 0) {result.append(new String(buffer, 0, readCount));}}// 获取结果信息logger.info("获取Result: {} ", result);// 断开连接channel.disconnect();session.disconnect();} catch (Exception e) {// 异常处理logger.error("执行 shell 脚本错误: {}", e.getMessage(), e);return "exec failed";}// 返回执行成功信息return "exec ok";}}
3.测试
我们通过页面访问进行简单测试 http://localhost:8088/shell/exec
后台执行结果如下: