Chegando saída da execução de um terminal de comando em um código java executado dentro de Cubieboard Plataforma

StackOverflow https://stackoverflow.com//questions/21019172

  •  21-12-2019
  •  | 
  •  

Pergunta

O código que estou utilizando para a execução de um terminal de comando no Linux Debian e obter a saída dentro de um programa java é este:

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();
}

Agora o problema é que ele funciona para comandos normais como ls / e dá de volta o resultado apropriado.Mas meu objetivo é executar comandos como:

echo 23 > /sys/class/gpio/export

qual é, por exemplo, para ativar o gpio pino no CubieBoard plataforma.(Cubieboard é uma mini-placa de pc como o Raspberry Pi).

Agora executando este comando no terminal do sistema em si, funciona bem e dá-me o bom resultado.Mas quando eu estou executando esse código java, eu não posso obter quaisquer resultados de volta.

O ponto é que, ele funciona e o comando executa bem, mas só que eu não posso começar a mensagem de saída do comando!

Por exemplo, se o pino estava ativo desde o passado, em seguida, normalmente ele deveria me dar de volta o resultado como:

bash: echo: write error: Device or resource busy

Mas quando eu executar este comando através de java de código acima, eu não obter qualquer resposta.(novamente ele tem efeito, mas apenas a resposta do terminal, eu não consigo!)

Quando eu executar o código, tanto stdInput e stdError variáveis no código estão a ter o valor null. :(

Por favor, ajude-me para que eu possa terminar o meu projeto.esta é a única parte remanescente :(

Obrigado.

Foi útil?

Solução 2

o código está certo, apenas na segunda linha, eu mudei

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

E tudo funciona!

sh == bash?

Por um longo tempo, /bin/sh usado para apontar para /bin/bash na maioria dos sistemas GNU/Linux.Como resultado, ele tinha quase se tornou seguro ignorar a diferença entre os dois.Mas isso começou a mudar recentemente.

Alguns exemplos de sistemas em que o /bin/sh não aponte para /bin/bash (e em alguns que não /bin/bash, pode até mesmo não existir) são:

  1. Moderno Debian e Ubuntu sistemas, que symlink sh para traço por padrão;

  2. O Busybox, que geralmente é executado durante o Linux tempo de arranque do sistema, como parte do initramfs.Ele usa o flash implementação de shell.

  3. BSDs.O OpenBSD usa o pdksh, um descendente do shell Korn.O FreeBSD é o sh é um descendente do original do UNIX shell Bourne.

Para obter mais informações sobre isso, consulte :Diferença entre o sh e o bash

Outras dicas

Há talvez a childProcess não executar até o fim

Por favor, tente:

proc.waitFor()

e executar leia stdInput e stdError em outro Thread antes de proc.waitFor().

Exemplo:

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();
        }
    }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top