简单的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"); // 建立连接,设定超时时间5s session.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
后台执行结果如下: