Java代码利用ch.ethz.ssh2对linux进行操作

方式一:

使用 h.ethz.ssh2.Session 的 execCommand 方法执行cmd指令
1.首先需要增加依赖

<dependency>
            <groupId>ch.ethz.ganymedgroupId>
            <artifactId>ganymed-ssh2artifactId>
            <version>build210version>
        dependency>

Java代码示例如下

 public static void main(String[] args) {
        makeFolder("127.0.0.520","userlocal","123",22,"/usr/local/at2.0/perfreport/","testwc");
    }

    public static void makeFolder(String ip, String username, String password, Integer  port,
                           String resultPath,String folderFront) {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //登录执行机
        Connection conn = null;
        ch.ethz.ssh2.Session session = null;
        try {
            conn = new Connection(ip,port);
            conn.connect();
            boolean flag = conn.authenticateWithPassword(username, password);// 认证֤
            if (!flag) {
                throw new BusinessException(ResponseMsg.FAILURE + "压测机IP、用户名或密码不正确!");
            }

            //从压测机拷贝执行报告到远程报告发布服务器
            session = conn.openSession();

            StringBuffer cmdStr = new StringBuffer();
            //去目标文件夹
            cmdStr.append("cd");
            cmdStr.append(" ");
            cmdStr.append(resultPath);
            cmdStr.append(";");
            //压缩
            cmdStr.append("mkdir");
            cmdStr.append(" ");
            cmdStr.append(folderFront);
            cmdStr.append(";");

            session.execCommand(cmdStr.toString());
        } catch (IOException e) {
            throw new BusinessException(ResponseMsg.FAILURE + "执行新建文件夹失败:", e.getCause());
        } finally {
            if(conn != null){
                conn.close();
            }
            if(session != null){
                session.close();
            }
        }
    }

方式二:
我们有时候不仅仅是需要执行cmd指令,我们还需要像黑窗口时一样获取指令的返回值

这时我们可以使用类似SFTPv3Client 等方式来获取返回值 。 这个同样是 ch.ethz.ssh2包下的,和上面的pom依赖是一样的。

   public static void main(String[] args) {
        System.out.println(ifExitFile("127.0.0.520", "userlocal", "123", 22, "/usr/local/at2.0/perfreport/"));
    }

    public static Boolean ifExitFile(String resultMachineIp, String resultMachineUsername,  String resultMachinePassword,
                              Integer resultMachinePort,  String resultMachinePath){
        //登录报告服务器
        Connection conn = null;
        ch.ethz.ssh2.Session session = null;
        int i =0;
        try {
            conn = new Connection(resultMachineIp, resultMachinePort);
            conn.connect();
            boolean flag = conn.authenticateWithPassword(resultMachineUsername, resultMachinePassword);// 认证֤
            if (!flag) {
                throw new BusinessException(ResponseMsg.FAILURE + "无法连接报告服务器");
            }

            //给文件夹目录赋权限
            session = conn.openSession();

            //判断是否有这个文件夹 如果有就删除
            SFTPv3Client sftpv3Client = new SFTPv3Client(conn);
            while (true){
                i++;
                boolean hasDir = false;
                try {
                    ch.ethz.ssh2.SFTPv3FileAttributes sftpAttrs = sftpv3Client.lstat(resultMachinePath);
                    hasDir = sftpAttrs.isDirectory();
                }catch(IOException e){
                }
                if (hasDir){
                    return true;
                }else {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if (i>10){
                        return false;
                    }
                }
            }

        } catch (IOException e) {
            throw new BusinessException(ResponseMsg.FAILURE + "查看文件是否存在失败:", e.getCause());
        } finally {
            if(conn != null){
                conn.close();
            }
            if(session != null){
                session.close();
            }
        }
    }

注意:
这个cmd指令是串行的,但仅仅只是cmd指令是串行执行的,他不会想我们的linux黑框框一样,等你收到返回值才执行下一步。
比如说我使用scp去复制文件到目标服务器,scp可能需要两秒,对目标服务器的文件进行解压 ,而此时很有可能文件还没有传完,解压指令就开始执行了,导致东西解压不成功。
所以就需要像 方法二 中的 ifExitFile方法,用来循环判断是否执行成功再走下一步。

再附赠几个我写的方法

//获取服务器文件的内容
  public String getFile(String ip, String username, String password,  String path) {
        //延时,等待文件传输完再获取
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 文件scp到数据服务器
        Connection conn = null;
        if (StringUtils.isNotBlank(path)){
            path  += "/"+STATISTICS_FILE;
        }
        try {
            conn = new Connection(ip);
            conn.connect();
            boolean flag = conn.authenticateWithPassword(username, password);// 认证֤
            if (!flag) {
                throw new BusinessException(ResponseMsg.FAILURE + "压测机IP、用户名或密码不正确!");
            }
            SCPClient client = new SCPClient(conn);
            try {
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                // 本地文件scp到远程目录
//                client.put(sourcePath, targetName, targetFolder, mode);
                client.get(path, baos);
                String errorFile = new String(baos.toByteArray(), "utf-8");
                return errorFile;
            } catch (IOException e) {
                throw new BusinessException(ResponseMsg.FAILURE + e.getCause().getMessage());
            }
        } catch (IOException e) {
            throw new BusinessException(ResponseMsg.FAILURE + "执行scp指令时出现异常:", e.getCause());
        } finally {
            conn.close();
        }
    }


    /**
     * @param ip           Linux服务器IP
     * @param username     Linux服务器用户名
     * @param password     Linux服务器密码
     * @param sourcePath   源文件全路径
     * @param targetName   目标文件名
     * @param targetFolder 目标文件夹全路径
     * @param mode         存取模式(chmod)
     * @throws IOException
     * @Description: 使用scp把脚本文件传送到远端服务器
     */
    public void transScriptToRemote(String ip, String username, String password, String sourcePath, String targetName,
                                    String targetFolder, String mode) {
        if (mode == null) {
            mode = "0600";
        }
        // 文件scp到数据服务器
        Connection conn = null;
        try {
            conn = new Connection(ip);
            conn.connect();
            boolean flag = conn.authenticateWithPassword(username, password);// 认证֤
            if (!flag) {
                throw new BusinessException(ResponseMsg.FAILURE + "压测机IP、用户名或密码不正确!");
            }
            SCPClient client = new SCPClient(conn);
            try {
                // 本地文件scp到远程目录
                client.put(sourcePath, targetName, targetFolder, mode);
            } catch (IOException e) {
                String message = e.getCause().getMessage();
                if (message.contains("No such file or directory")) {
                    Session session = conn.openSession();
                    session.execCommand("mkdir " + targetFolder);
                    // 本地文件scp到远程目录
                    client.put(new String(sourcePath.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1),
                            new String(targetName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1), targetFolder, mode);
                } else {
                    throw new BusinessException(ResponseMsg.FAILURE + e.getCause().getMessage());
                }
            }
        } catch (IOException e) {
            throw new BusinessException(ResponseMsg.FAILURE + "执行scp指令时出现异常:", e.getCause());
        } finally {
            conn.close();
        }
    }




你可能感兴趣的:(java,linux,python)