Chegando saída da execução de um terminal de comando em um código java executado dentro de Cubieboard Plataforma
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.
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:
Moderno Debian e Ubuntu sistemas, que symlink sh para traço por padrão;
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.
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();
}
}