java向linux服务器发送命令

「这是我参与2022首次更文挑战的第13天,活动详情查看:2022首次更文挑战」。

本文介绍通过javalinux服务器发送执行命令,通常大家都是使用XshellFinalShell,使用java操作Linux,主要有三种方法:
1、使用JDK自带的RunTime类和Process实现本地操作linux服务器
2、使用ganymed-ssh2 操作远程linux服务器
3、使用jsch远程连接操作linux服务器
本文介绍后两种方法,在这之前先创建一个公共的方法,用于打印发送指令后返回的信息和异常信息

private String consumeStream(InputStream stdout) throws Exception {
    // 执行之后的流
    BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
    String s ;
    StringBuilder sb = new StringBuilder();
    while((s=br.readLine())!=null){
        // 循环打印所有数据
        sb.append(s);
        System.out.println(s);
    }
    return sb.toString();
}
复制代码

使用ganymed-ssh2 操作远程linux服务器

通过maven引入jar包

<!-- ganymed-ssh2 远程调用linux -->
<dependency>
    <groupId>ch.ethz.ganymed</groupId>
    <artifactId>ganymed-ssh2</artifactId>
    <version>262</version>
</dependency>
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.5</version>
</dependency>
复制代码

创建会话并发送命令

public void execGanymed() throws IOException {
        // 连接服务器地址
        Connection conn = new Connection("服务器ip地址",连接端口一般为22);
        // 开启连接
        conn.connect();
        // 验证用户密码
        conn.authenticateWithPassword("用户名", "密码");
        // 创建链接的 session
        Session session = conn.openSession();
        // 执行命令
        String execCode = "cd /data/jar/ming/ming-service/&&ls";
        System.out.println("执行的命令: " + execCode);
        session.execCommand(execCode);
        // 消费所有输入流
        String inStr = consumeStream(session.getStdout());
        // 执行错误
        String errStr = consumeStream(session.getStderr());

        session.close();
        conn.close();
    }
复制代码

这里发送了两段代码:
1、进入 /data/jar/ming/ming-service 路径下
2、ls 命令查看文件夹下所有文件夹和文件

##jsch远程连接操作linux服务器

通过maven添加jar包

<!-- jsch 远程调用linux -->
<dependency>
    <groupId>com.jcraft</groupId>
    <artifactId>jsch</artifactId>
    <version>0.1.51</version>
</dependency>
<dependency>
    <groupId>org.apache.maven.archetype</groupId>
    <artifactId>maven-archetype</artifactId>
    <version>3.1.2</version>
</dependency>
复制代码

创建会话并发送命令

public void execJsch() throws Exception {
    // 创建JSch
    JSch jSch = new JSch();
    // 获取session
    Session session = jSch.getSession("用户名", "服务器ip地址", 连接地址一般为22);
    session.setPassword("密码");
    Properties prop = new Properties();
    // 有三种配置
    // StrictHostKeyChecking=no 使用用户名密码登录设置为这个,当然也是最不安全的连接方式
    // StrictHostKeyChecking=ask 默认的安全机制
    // StrictHostKeyChecking=yes 最高的安全机制
    prop.put("StrictHostKeyChecking", "no");
    session.setConfig(prop);
    // 启动连接
    session.connect();
    ChannelExec exec = (ChannelExec)session.openChannel("exec");
    // 注意这里执行要 java -jar 的命令需要把环境变量给加载进来,通过 source /etc/profile 这一句命令加载环境变量
    // 其实最终我们需要的只是 jdk 加载好就行了
    exec.setCommand("source /etc/profile &&cd /data/jar/ming/ming-service&&ls");
    exec.setInputStream(null);
    exec.setErrStream(System.err);
    exec.connect();

    // 消费所有输入流,必须在exec之后
    String inStr = consumeInputStream(exec.getInputStream());
    String errStr = consumeInputStream(exec.getErrStream());

    exec.disconnect();
    session.disconnect();
}
复制代码

这里发送了三段代码,每段代码直接使用 && 连接:
1、通过 source /etc/profile 命令添加环境变量
2、进入 /data/jar/ming/ming-service 路径下
3、ls 命令查看文件夹下所有文件夹和文件

可能遇到的问题

java.io.IOException: A remote execution has already started.

命令执行使用 execCommand ,每个session中只能执行一次execCommand,执行多次会报以上错误。

查看 jdk 安装路径

echo $JAVA_HOME

Guess you like

Origin juejin.im/post/7062728679905820708