Ler saida de comandos Linux com Java [Resolvido]

Olá pessoal!

Consegui rodar o comando lspci com Java, mas na hora de ler a saida do comando com o método readLine() só mostra a primeira linha, conforme a imagem abaixo:

O Código é o seguinte:

[code]private void executarButtonActionPerformed(java.awt.event.ActionEvent evt) {

    try
	{

               Process proc = Runtime.getRuntime().exec("/bin/lspci");
               BufferedReader output = new BufferedReader(
               new InputStreamReader (proc.getInputStream()));
               outputTextArea.setText(output.readLine());
               output.close();

	}
	  catch(IOException e)
	      {
		  JOptionPane.showMessageDialog(null,e.getMessage());
	      }
   

}                    

[/code]

Ainda não descobri como mostrar a saida completa do comando.

[]s

1 curtida

Você precisa iterar o readLine. Algo como:

...
String line;
do {
   line = output.readLine();
   // Código para ADICIONAR a nova line na sua TextArea.
} while(line != null);
...

Eu não cheguei a testar no seu código.

[]'s

Somente para sua referência:

http://java.sun.com/javase/6/docs/api/java/io/BufferedReader.html#readLine()

Com o método readLine() não deu não, nem colocando um laço. Creio que o método readLine() não seja o indicado para este procedimento de ler saida de comandos no Linux.
Ainda tô procurando alguma classe que possua um método que sirva neste link:
http://java.sun.com/javase/6/docs/api/

Mas ainda não achei…

Testei com o OutputStream() da classe Process e tb não deu certo.
Alguma idéia?

[]s

A minha sugestão é você chamar o método waitFor() da classe Process antes de ler o OutputStream. Assim você terá certeza que a execução do comando terminou e tudo que ele deveria escrever no buffer foi escrito.

[]'s.

Já resolveu? Se não, tenta dessa maneira:

InputStream in = null; Process proc= Runtime.getRuntime().exec("comando"); in = proc.getInputStream(); int c; while ((c = in.read()) != -1) { outputTextArea.setText(String.valueOf((char) c)); }

Olá pessoal!

Ao colocar o waitFor() da dica do Kaique mostra somente a primeira linha e ao colocar o while da dica do Molmedo a aplicação trava e não responde. Cheguei até a copiar o código pra ver se era problema da IDE e mesmo assim não deu.

Usei este código para o método waitFor()

try {
            Process proc = Runtime.getRuntime().exec(comandoTextField.getText());
        try {
                proc.waitFor();
                BufferedReader output = new BufferedReader(
                new InputStreamReader (proc.getInputStream()));
                outputTextArea.setText(output.readLine());
                output.close();
            } 
                catch (InterruptedException ex) {
                Logger.getLogger(PrincipalJFrame.class.getName()).log(Level.SEVERE, null, ex);
            }
      }
		catch(IOException e)
		{
			JOptionPane.showMessageDialog(null,e.getMessage());
		}

Valeu pela força, a saga continua. :wink:

Cara, muito esquisito esse seu problema. Já verificou se a resposta do comando realmente retorna mais de uma linha?
O que o método waitFor() irá fazer é “segurar” a execução do seu programa enquanto o processo que foi iniciado não terminar.
Faça o seguinte, utilize o trecho de código abaixo:

import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;

public class Caller {

	public static void main(String[] args) {

		try {
			Scanner scanner = new Scanner(System.in);
			String line = scanner.nextLine();

			Process process = Runtime.getRuntime().exec(line);
			process.waitFor();

			InputStream inputStream = process.getInputStream();
			byte[] content = new byte[inputStream.available()];
			inputStream.read(content);

			System.out.println(new String(content));
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

	}

}

Funciona da seguinte maneira: execute a classe e, no prompt de comando, escreva o comando que deseja ser executado e tecle enter. Assim que terminar a execução do processo, o resultado será impresso na tela, tal como se você utilizasse o próprio prompt de comando para executar o pocesso.
Depois de fazer isso, nos avise se deu certo…

[EDIT]
O seu código está certo com a utilização do waitFor(). O problema é que você lê somente a primeira linha do inputStream. Tente ler todo o conteúdo existente que provavelmente irá funcionar.
Só agora percebi isso quando fui ler o seu código… :slight_smile:
[/EDIT]

[]'s.

Kaique, seu código deu certo:

run:
lspci
00:00.0 Host bridge: VIA Technologies, Inc. P4M890 Host Bridge
00:00.1 Host bridge: VIA Technologies, Inc. P4M890 Host Bridge
00:00.2 Host bridge: VIA Technologies, Inc. P4M890 Host Bridge
00:00.3 Host bridge: VIA Technologies, Inc. P4M890 Host Bridge
00:00.4 Host bridge: VIA Technologies, Inc. P4M890 Host Bridge
00:00.5 PIC: VIA Technologies, Inc. P4M890 I/O APIC Interrupt Controller
00:00.6 Host bridge: VIA Technologies, Inc. P4M890 Security Device
00:00.7 Host bridge: VIA Technologies, Inc. P4M890 Host Bridge
00:01.0 PCI bridge: VIA Technologies, Inc. VT8237 PCI Bridge
00:02.0 PCI bridge: VIA Technologies, Inc. P4M890 PCI to PCI Bridge Controller
00:03.0 PCI bridge: VIA Technologies, Inc. P4M890 PCI to PCI Bridge Controller
00:0a.0 Network controller: RaLink RT2561/RT61 802.11g PCI
00:0f.0 IDE interface: VIA Technologies, Inc. VT8237A SATA 2-Port Controller (rev 80)
00:0f.1 IDE interface: VIA Technologies, Inc. VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE (rev 07)
00:10.0 USB Controller: VIA Technologies, Inc. VT82xxxxx UHCI USB 1.1 Controller (rev a0)
00:10.1 USB Controller: VIA Technologies, Inc. VT82xxxxx UHCI USB 1.1 Controller (rev a0)
00:10.2 USB Controller: VIA Technologies, Inc. VT82xxxxx UHCI USB 1.1 Controller (rev a0)
00:10.3 USB Controller: VIA Technologies, Inc. VT82xxxxx UHCI USB 1.1 Controller (rev a0)
00:10.4 USB Controller: VIA Technologies, Inc. USB 2.0 (rev 86)
00:11.0 ISA bridge: VIA Technologies, Inc. VT8237A PCI to ISA Bridge
00:11.7 Host bridge: VIA Technologies, Inc. VT8251 Ultra VLINK Controller
00:12.0 Ethernet controller: VIA Technologies, Inc. VT6102 [Rhine-II] (rev 7c)
00:13.0 PCI bridge: VIA Technologies, Inc. VT8237A Host Bridge
02:00.0 VGA compatible controller: nVidia Corporation GeForce 6500 (rev a1)
04:01.0 Audio device: VIA Technologies, Inc. VIA High Definition Audio Controller (rev 10)

CONSTRUÍDO COM SUCESSO (tempo total: 11 segundos)

Não entendo o motivo do BufferedReader ou o readLine() não mostrar a saída do comando como foi feito usando a classe Scanner.

Esta linha transforma o texto em byte?

byte[] content = new byte[inputStream.available()];

Abraço!

Simples, quando você chama o método readLine(), ele vai te retornar somente uma linha do buffer que se encontra na isntância da classe BufferedReader. Lembre-se que quando você vai instanciar essa classe, você passa um InputStream no construtor, que simplesmente são todos os bytes gerados pelo processo que você executou.

Não. Essa linha cria um array de bytes com o tamanho exato do conteúdo gerado pelo processo que você executou. Na realiade, o que você faz é o contrário: transforma os bytes em texto. É o que eu faço na linha que mando imprimir na tela. Dá uma olhada no código.

[]'s.

Tô de volta pra informar que consegui resolver o problema com a ajuda do TBispo. :lol:

Aqui está o resultado:

Grato a todos que ajudaram neste tópico.

[]s