java 执行shell命令(分批 多条 走一步看一步的执行)

说明

网上有很多通过java执行命令的程序,但是只能执行一条命令,或者是所有命令一次性执行完毕。
而我想要的是执行一条命令,看一看返回结果,然后在去执行下一条命令,可惜翻遍全网,竟然一个可行的方法都没有!!!
没办法,自己想办法解决吧。

实现代码

废话不多说,直接上代码:

入口类

import core.CmdClient;

public class Main
{
    public static void main(String[] args)
    {
        CmdClient client = new CmdClient();
        client.run("cd /");
        client.run("ls");
        client.run("exit");
        System.out.println("主线程结束");
    }
}

核心代码类:
这里就尽量不写的太复杂,把多线程直接的交互都给砍掉了。大家可以根据自己需求去修改。

package core;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

public class CmdClient
{
    // 中文有乱码的可以试着改一下编码格式。
    private static final Charset charset = StandardCharsets.UTF_8;
    // 初始化
    public CmdClient()
    {
        try
        {
            /*
              Runtime.getRuntime().exec()方法本质和windows上的运行一样,只能执行一个命令来启动一个程序。
              这里启动的是sh解释器,可以根据需要改成其他shell解释器。适用mac,linux系统。
              对于windows,则是运行C:\Windows\System32\cmd.exe,同时执行的也不是shell命令,而是dos命令。
             */
            Process process = Runtime.getRuntime().exec("/bin/sh");
            // 获取程序的输出流和输入流
            inputStream = process.getInputStream();
            errorStream = process.getErrorStream();
            outputStream = process.getOutputStream();
            /*
              输出数据需要,若执行的命令没有输出结果,就会阻塞读取流的线程。
              为了防止主线程被阻塞,所以声明新的线程专门盯着输出数据。
             */
            new Thread(this::ReadCmdOut).start();
            new Thread(this::ReadCmdError).start();
        }
        catch (IOException e)
        { throw new RuntimeException("cmd初始化异常", e); }
        System.out.println("控制台初始化完毕");
    }

    private final InputStream inputStream;
    private final InputStream errorStream;
    private final OutputStream outputStream;

    // 运行命令
    public void run(String cmd)
    {
        try
        {
        	// 若执行某些命令出现异常,可以尝试更换 \n 为 \r 或 \n\r
            outputStream.write((cmd + "\n").getBytes(charset));
            outputStream.flush();
        }
        catch (Exception e)
        { throw new RuntimeException("命令执行错误:" + cmd, e); }
    }

    private void ReadCmdOut()
    {
        try
        { print(inputStream); }
        catch (Exception e)
        { throw new RuntimeException("获取输出流异常", e); }
        System.out.println("正常输出流结束");
    }

    private void ReadCmdError()
    {
        try
        { print(errorStream); }
        catch (Exception e)
        { throw new RuntimeException("获取错误流异常", e); }
        System.out.println("异常输出流结束");
    }

    /**
     * 这里直接把数据打印出来了,有其他需求的可以在这里写判来确定下一步来执行什么。
     */
    private void print(InputStream inputStream) throws IOException
    {
        byte[] bytes = new byte[1024];
        int i;
        while (true)
        {
            i = inputStream.read(bytes);
            if (i == -1) break;
            System.out.print(new String(bytes, 0, i, charset));
        }
        System.out.println();
    }
}
  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值