简体   繁体   English

使用 processBuilder 执行 shell 命令并与之交互

[英]Execute a shell command using processBuilder and interact with it

I'm trying to create a program allowing me to execute a command through a terminal (which is OmxPlayer for raspberry pi if you want to know) with arguments, but i'd want to be able to interact with it once I have launched the command.我正在尝试创建一个程序,允许我通过带有参数的终端(如果您想知道,它是用于树莓派的 OmxPlayer)执行命令,但我希望能够在启动后与它进行交互命令。

For example i'd want to do : omxplayer -win x1 y1 x2 y2 and then be able to press "p" to pause the video/audio media例如我想做: omxplayer -win x1 y1 x2 y2 然后可以按“p”暂停视频/音频媒体

I already have something that can launch the omxplayer with arguments (actually it's "ls" but it should work exactly the same way) but I don't understand how to interact with the terminal once i've launched the command through the processBuilder.我已经有了一些可以用参数启动 omxplayer 的东西(实际上它是“ls”,但它应该以完全相同的方式工作)但是我不明白一旦我通过 processBuilder 启动命令后如何与终端交互。

Here's what i've got at the moment :这是我目前所拥有的:

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

public class Main1 {

    public static void main(String a[]){

        InputStream is = null;
        ByteArrayOutputStream baos = null;
        List<String> commands = new ArrayList<String>();
        commands.add("ls");
        commands.add("-l");
        commands.add("/");
        ProcessBuilder pb = new ProcessBuilder(commands);
        try {
            Process prs = pb.start();
            is = prs.getInputStream();
            byte[] b = new byte[1024];
            int size = 0;
            baos = new ByteArrayOutputStream();
            while((size = is.read(b)) != -1){
                baos.write(b, 0, size);
            }
            System.out.println(new String(baos.toByteArray()));
        } 
        catch (IOException e) 
        {
            e.printStackTrace();
        } 
        finally
        {
            try {
                if(is != null) is.close();
                if(baos != null) baos.close();
            } catch (Exception ex){}
        }
    }
}

"(actually it's "ls" but it should work exactly the same way)" “(实际上它是“ls”,但它的工作方式应该完全相同)”

No, it is not.不它不是。 Because the 'ls' process returns immediately after its call.因为“ls”进程在调用后立即返回。 Your omixplayer at the other hand is interactive and will accept commands at runtime.另一方面,您的 omixplayer 是交互式的,并且会在运行时接受命令。

What you have to do:你必须做的:

  • create a class which implements Runnable and let this class read from the prs.getInputStream().创建一个实现 Runnable 的类并让这个类从 prs.getInputStream() 中读取。 You will need this because the .read() will block and wait for new data to read.您将需要它,因为 .read() 将阻塞并等待读取新数据。

  • get the OutputStream of the Process object (prs.getOutputStream()).获取 Process 对象的 OutputStream (prs.getOutputStream())。 Everything you write to the OutputStream will be read from your omixplayer.您写入 OutputStream 的所有内容都将从您的 omixplayer 中读取。 Don't forget to flush the OutputStream and every command needs an "\\n" at the end to be executed.不要忘记刷新 OutputStream 并且每个命令都需要在末尾加上“\\n”才能执行。

Like that:像那样:

public class TestMain {
    public static void main(String a[]) throws InterruptedException {

        List<String> commands = new ArrayList<String>();
        commands.add("telnet");
        commands.add("www.google.com");
        commands.add("80");
        ProcessBuilder pb = new ProcessBuilder(commands);
        pb.redirectErrorStream(true);
        try {

            Process prs = pb.start();
            Thread inThread = new Thread(new In(prs.getInputStream()));
            inThread.start();
            Thread.sleep(2000);
            OutputStream writeTo = prs.getOutputStream();
            writeTo.write("oops\n".getBytes());
            writeTo.flush();
            writeTo.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

class In implements Runnable {
    private InputStream is;

    public In(InputStream is) {
        this.is = is;
    }

    @Override
    public void run() {
        byte[] b = new byte[1024];
        int size = 0;
        try {
            while ((size = is.read(b)) != -1) {
                System.err.println(new String(b));
            }
            is.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}

PS: Keep in mind this example is quick an dirty. PS:请记住,这个例子很快很脏。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM