简体   繁体   English

获取在Cubieboard Platform内运行的java代码中执行终端命令的输出

[英]Getting output from executing a terminal command in a java code running inside Cubieboard Platform

The code that I am using for running a terminal command in Linux Debian and getting the output inside a java program is this: 我用于在Linux Debian中运行终端命令并在java程序中获取输出的代码是:

public static String execute(String command) {
    StringBuilder sb = new StringBuilder();
    String[] commands = new String[]{"/bin/sh", "-c", command};
    try {
        Process proc = new ProcessBuilder(commands).start();
        BufferedReader stdInput = new BufferedReader(new
                InputStreamReader(proc.getInputStream()));

        BufferedReader stdError = new BufferedReader(new
                InputStreamReader(proc.getErrorStream()));

        String s = null;
        while ((s = stdInput.readLine()) != null) {
            sb.append(s);
            sb.append("\n");
        }

        while ((s = stdError.readLine()) != null) {
            sb.append(s);
            sb.append("\n");
        }
    } catch (IOException e) {
        return e.getMessage();
    }
    return sb.toString();
}

Now the problem is, it works for normal commands like ls / and gives back the appropriate result. 现在问题是,它适用于像ls /这样的普通命令,并返回适当的结果。 But my goal is to run commands like: 但我的目标是运行如下命令:

echo 23 > /sys/class/gpio/export

which is, for example, for activating the gpio pin in the CubieBoard platform. 例如,用于激活CubieBoard平台中的gpio引脚。 (Cubieboard is a mini-pc board like Raspberry Pi). (Cubieboard是像Raspberry Pi一样的迷你PC板)。

Now running this command in the terminal of the system itself, works fine and gives me the proper result. 现在在系统终端中运行此命令,工作正常并给我正确的结果。 But when i am running it from this java code, i cannot get any results back. 但是当我从这个java代码运行它时,我无法获得任何结果。

The point is that, it works and the command executes well, but just that i cannot get the output message of the command! 关键是,它工作正常,命令执行得很好,但只是我无法得到命令的输出消息!

For example if the pin was active from the past, then normally it should give me back the result like: 例如,如果引脚从过去开始处于活动状态,那么通常情况下它应该会返回结果,如:

bash: echo: write error: Device or resource busy

But when i run this command through java code above, i do not get any response back. 但是当我通过上面的java代码运行此命令时,我没有得到任何回复。 (again it takes effect but just the response of the terminal i cannot get!) (它再次生效,但只是终端的响应,我无法得到!)

When i run the code, both stdInput and stdError variables in the code are having the value null . 当我运行代码时,代码中的stdInputstdError变量都具有null :( :(

Please help me so that i can finish my project. 请帮助我,以便我可以完成我的项目。 this is the only part that is remaining :( 这是唯一剩下的部分:(

Thank you. 谢谢。

There maybe the childProcess doesn't run to end 也许childProcess没有运行结束

Please to try: 请尝试:

proc.waitFor() proc.waitFor()

and run read stdInput and stdError in other Thread before proc.waitFor() . 并在proc.waitFor()之前在其他Thread中运行read stdInput和stdError。

Example: 例:

public static String execute(String command) {
        String[] commands = new String[] { "/bin/sh", "-c", command };

        ExecutorService executor = Executors.newCachedThreadPool();
        try {
            ProcessBuilder builder = new ProcessBuilder(commands);

            /*-
            Process proc = builder.start();
            CollectOutput collectStdOut = new CollectOutput(
                    proc.getInputStream());
            executor.execute(collectStdOut);

            CollectOutput collectStdErr = new CollectOutput(
                    proc.getErrorStream());
            executor.execute(collectStdErr);
            // */

            // /*-
            // merges standard error and standard output
            builder.redirectErrorStream();
            Process proc = builder.start();
            CollectOutput out = new CollectOutput(proc.getInputStream());
            executor.execute(out);
            // */
            // child proc exit code
            int waitFor = proc.waitFor();

            return out.get();
        } catch (IOException e) {
            return e.getMessage();
        } catch (InterruptedException e) {
            // proc maybe interrupted
            e.printStackTrace();
        }
        return null;
    }

    public static class CollectOutput implements Runnable {
        private final StringBuffer buffer = new StringBuffer();
        private final InputStream inputStream;

        public CollectOutput(InputStream inputStream) {
            super();
            this.inputStream = inputStream;
        }

        /*
         * (non-Javadoc)
         * 
         * @see java.lang.Runnable#run()
         */
        @Override
        public void run() {
            BufferedReader reader = null;
            String line;
            try {
                reader = new BufferedReader(new InputStreamReader(inputStream));
                while ((line = reader.readLine()) != null) {
                    buffer.append(line).append('\n');
                }
            } catch (Exception e) {
                System.err.println(e);
            } finally {
                try {
                    reader.close();
                } catch (IOException e) {
                }
            }

        }

        public String get() {
            return buffer.toString();
        }
    }

the code is right, just in the second line, I changed 代码是对的,就在第二行,我改变了

"/bin/sh" to "/bin/bash"

And everything works! 一切正常!

sh == bash? sh == bash?

For a long time, /bin/sh used to point to /bin/bash on most GNU/Linux systems. 很长一段时间,/ bin / sh曾经指向大多数GNU / Linux系统上的/ bin / bash。 As a result, it had almost become safe to ignore the difference between the two. 结果,忽略两者之间的差异几乎是安全的。 But that started to change recently. 但最近这种情况开始发生变化。

Some popular examples of systems where /bin/sh does not point to /bin/bash (and on some of which /bin/bash may not even exist) are: / bin / sh未指向/ bin / bash(以及其中某些/ bin / bash甚至可能不存在)的系统的一些常见示例是:

  1. Modern Debian and Ubuntu systems, which symlink sh to dash by default; 现代Debian和Ubuntu系统,默认情况下符号链接为破折号;

  2. Busybox, which is usually run during the Linux system boot time as part of initramfs. Busybox,通常在Linux系统启动时作为initramfs的一部分运行。 It uses the ash shell implementation. 它使用ash shell实现。

  3. BSDs. BSD系统。 OpenBSD uses pdksh, a descendant of the Korn shell. OpenBSD使用了Korn shell的后代pdksh。 FreeBSD's sh is a descendant of the original UNIX Bourne shell. FreeBSD的sh是原始UNIX Bourne shell的后代。

For more information on this please refer to : Difference between sh and bash 有关这方面的更多信息,请参阅: sh和bash之间的区别

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

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