java jsch执行远程sh脚本文件(.sh)不生效问题踩的坑

jsch是一个提供java ssh远程连接和执行命令的工具jar包,其中关于执行命令时两种方式:

1、ChannelExec channel = (ChannelExec) session.openChannel("exec");

2、ChannelShell channel = (ChannelShell) session.openChannel("shell");

以下给出方法样列:

<!-- jsch支持 -->
<dependency>
    <groupId>com.jcraft</groupId>
    <artifactId>jsch</artifactId>
    <version>0.1.55</version>
</dependency>
package cn.objectspace.webssh.websocket;

import cn.hutool.core.io.IoUtil;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.ChannelShell;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;

public class JSchDemo {

    private String ipAddress;   //主机ip
    private String username;   // 账号
    private String password;   // 密码
    private int port;  // 端口号
    Session session;

    public JSchDemo(String ipAddress, String username, String password, int port) {
        this.ipAddress = ipAddress;
        this.username = username;
        this.password = password;
        this.port = port;
    }

    public void connect() {
        try {
            JSch jsch = new JSch();
             session = jsch.getSession(username, ipAddress, port);
            session.setPassword(password);
            //设置首次登录跳过主机检查
            session.setConfig("StrictHostKeyChecking", "no");
            //设置登录超时时间
            session.connect(3000);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    public int executeExec(String command) {
        int returnCode = 0;
        ChannelExec channel = null;
        PrintWriter printWriter = null;
        BufferedReader input = null;
        try {
            channel = (ChannelExec) session.openChannel("exec");
            channel.setCommand(command);
            InputStream in = channel.getInputStream();
            channel.connect();

            BufferedReader inputReader = new BufferedReader(new InputStreamReader(in, "GBK"));
            String inputLine;
            while ((inputLine = inputReader.readLine()) != null) {
                System.out.println(inputLine);
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return -1;
        } finally {
            IoUtil.close(printWriter);
            IoUtil.close(input);
            if (channel != null) {
                channel.disconnect();
            }
        }
        return returnCode;
    }

    public int executeShell(String command) {
        int returnCode = 0;
        ChannelShell channel = null;
        PrintWriter printWriter = null;
        BufferedReader input = null;
        StringBuffer stringBuffer = new StringBuffer();
        try {
            channel = (ChannelShell) session.openChannel("shell");
            channel.connect();

            //获取输入
            InputStreamReader inputStreamReader = new InputStreamReader(channel.getInputStream());
            input = new BufferedReader(inputStreamReader);

            //输出
            printWriter = new PrintWriter(channel.getOutputStream());
            printWriter.println(command);
            printWriter.println("exit");
            printWriter.flush();
            String line;
            while ((line = input.readLine()) != null) {
                stringBuffer.append(line + "\n") ;
            }
            System.out.println("输出:\n" + stringBuffer);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return -1;
        }finally {
            IoUtil.close(printWriter);
            IoUtil.close(input);
            if (channel != null) {
                channel.disconnect();
            }
        }
        return returnCode;
    }

    public void close(){
        if (session != null) {
            session.disconnect();
        }
    }
}

这两种执行.sh脚本时存在差别,例如有一个test.sh脚本,在服务器/home目录下,且已经给予权限

chmod +x /home/test.sh

#!/bin/bash

mkdir -p /home/test

调用时会发现二者的差异

public class test {
    public static void main(String[] args) {
        JSchDemo jSchDemo = new JSchDemo("192.168.1.180", "root", "", 22);

        jSchDemo.connect();
        jSchDemo.executeExec("pwd");
        System.out.println("========");
        jSchDemo.executeExec("/home/test.sh");
        //jSchDemo.executeShell("/home/test.sh");
        jSchDemo.executeShell("ls /home");

        jSchDemo.close();
    }
}

当你使用ChannelExec,会发现目录/home/test目录并没有创建

 jSchDemo.executeExec("/home/test.sh");

/home
========

而当使用ChannelShell,则创建正常

jSchDemo.executeShell("/home/test.sh");

/home
========
test

 移除创建的文件夹

rm -rf /home/test

对于ChannelExec,正确的执行.sh脚本命令是,即前面加上sh

 jSchDemo.executeExec("sh /home/test.sh");

/home
========
test

不知道ChannelExec执行.sh脚本是否还有其他方式,希望大佬们有建议则在评论区留个言

另外,如果需要后台执行某个命令,不能直接 <命令> + & 的方式执行,这样可能在 JSch 中不生效,建议写成这样的格式:<命令> > /dev/null 2>&1 &

文档引用:

Java打造一款SSH客户端,而且已开源_java ssh客户端-CSDN博客

java程序使用Jsch 实现 ssh连接_java jsch-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值