Jump to content
Hipnoted

[Dúvida] Executar comando de sistema em Java

Recommended Posts

Hipnoted

Alguém me pode dizer como se faz correctamente para executar um comando de sistema? Eu sei que é com o Runtime.exec mas ainda não descobri a forma.

O que eu pretendo é obter algo semelhante ao system em C. Exemplo:

system("vmstat > file.txt");

Com isto a informação resultante do comando vmstat passaria a estar disponível no ficheiro file.txt e podia ler esse ficheiro quando quizesse.

Eu pretendo é fazer o mesmo mas em Java. Desde já agradeço ajuda. ;)


"Nunca discutas com um idiota. Eles arrastam-te até ao seu nível e depois ganham-te em experiência"

Share this post


Link to post
Share on other sites
Knitter

Runtime.getRuntime().exec(<comando a executar>);

Pode ser o que procuras, dependendo do objectivo. O que o método faz é criar um processo separado e executar o comando, nada de expecial. Pelo que vi na documentação, apesar de existirem vários métodos 'exec()', o que recebe apenas um argumento do tipo String é o recomendado...

Share this post


Link to post
Share on other sites
Hipnoted

Eu já tentei dessa forma mas não consegui criar o ficheiro com a informação gerada pelo comando. Fiz uma coisa do tipo:

Runtime.getRuntime().exec("vmstat > file.txt");

Também já tentei de uma forma em que o exec recebe três argumentos e em que supostamente um deles seria a localização de onde iria ficar o ficheiro. Mas também não consegui.

Se alguém já fez isso e sabe como se faz agradeço. ;)


"Nunca discutas com um idiota. Eles arrastam-te até ao seu nível e depois ganham-te em experiência"

Share this post


Link to post
Share on other sites
Hipnoted

Bem já consegui resolver o problema parcialmente. Depois de tanto pesquisar no google sempre descobri. :D

Fica aqui a resposta:


import java.io.*;
import java.util.*;

public class Comando{
    public static void main(String args[]) throws IOException {

         if (args.length <= 0) {
            System.err.println("Need command to run");
            System.exit(-1);
         }

        Runtime runtime = Runtime.getRuntime();
        Process process = runtime.exec(args);
        InputStream is = process.getInputStream();
        InputStreamReader isr = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(isr);
        String line; 

        System.out.printf("Output of running %s is:", Arrays.toString(args));

        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }
    }
}

O que este código faz é receber um comando pala consola e executa-o como no sistema.

Por exemplo:

$ java Comando ls

$ ls

Postei aqui o código porque penso ser interessante. ;)

Só não consegui foi obter alguns dados do comando usando pipes porque quando fazia line = br.readLine() devolvia null  ;)

Mas pronto já deu alguma coisa.


"Nunca discutas com um idiota. Eles arrastam-te até ao seu nível e depois ganham-te em experiência"

Share this post


Link to post
Share on other sites
HecKel

Visto que o programa é executado na consola, o pipe é verificado pelo promp como um pipe..., portanto nem chega a ir para o java como argumento daí o null.

Experimenta a fazeres algo similar, mas em vez de mandares o comando por argumento do main fazeres a receber os dados com um Scanner ou algo do género :D Aposto que assim não irás ter dificuldades em implementar :)

abraços, HecKel

Share this post


Link to post
Share on other sites
Hipnoted

Experimenta a fazeres algo similar, mas em vez de mandares o comando por argumento do main fazeres a receber os dados com um Scanner ou algo do género :D Aposto que assim não irás ter dificuldades em implementar :)

É um caso a ver mas acho que já tentei. O código que postei acima é apenas um exemplo. O que eu quero realmente é saber 4 valores do CPU dados pelo vmstat.

Pretento o seguinte comando:  vmstat | tail -1 | tr -s ' ' | cut -f14,15,16,17 -d ' '

Ou seja tentei algo do género:

...

Runtime runtime = Runtime.getRuntime();
        Process process = runtime.exec(" vmstat | tail -1 | tr -s ' ' | cut -f14,15,16,17 -d ' ' ");
        InputStream is = process.getInputStream();
        InputStreamReader isr = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(isr);
        String line; 
  
        line = br.readLine();

...

Mas line ficava com null...


"Nunca discutas com um idiota. Eles arrastam-te até ao seu nível e depois ganham-te em experiência"

Share this post


Link to post
Share on other sites
HecKel

Sim, era a isso que eu me referia.

Já tive um trabalho similar na faculdade, se queres enviar os comandos pela consola deverás fazer um parse da string e fazer um split pelos pipes e executar num ciclo cada posição do array de strings, se quiseres fazer dessa forma tens mesmo de as parcelar simulando o ciclo que te referi antes.

O exec deve executar o comando todo, mas visto que se trata de pipes deve se atrofiar no que vai enviar para o buffer.

abraços, HecKel

Share this post


Link to post
Share on other sites
magician

Já tentaram usa a class Program do SWT ?

Eu uso muito para tipo em links ao clicar mando como argumento um http e ele abre o browser default do sistema com o link dado tipo

Program.execute("http://www.google.pt") 

a vantagem do Program é que basta colocar uma string com o que se quer executar e ele proprio procura no sistema e executa e para alem disso tem mais metodos bastante uteis.


I haven’t lost my mind; it’s backed up on DVD somewhere!

Share this post


Link to post
Share on other sites
Rui Carlos

o 'exec' (pelo menos em C) só executa um comando!!!

quando numa bash lhe damos um comando com '|', '<', expressões regulares, etc. a bash transforma o comando (eventualmente em vários) antes de o(s) executar com o 'exec' ou outra função semelhante.

em C fazer 'system("ls > file.txt")' funciona como deve ser mas 'exec("ls > file.txt")' já não. para por isso com o 'exec' tinhamos que associar ao stdout o ficheiro 'file.txt' antes de executar o 'ls'.

não sei se existe alguma função em Java para executar comandos a partir de uma bash (tendo em conta que isto depende do SO é provável que não exista), se não existir experimenta fazer:

String [] cmd={"bash","-c","vmstat > file.txt"};
Runtime.getRuntime().exec(cmd);

Share this post


Link to post
Share on other sites
Hipnoted

Obrigado a todos pelas respostas.

Thanks Rui Carlos era mesmo isso. :D

Já agora e para não abrir outro tópico, alguém sabe de métodos que permitam obter estes dados sem recorrer ao Runtime.exec?

E já agora também precisava de obter o uptime (tempo que o PC está ligado) sem ler o ficheiro /proc/uptime .

É que se funcionar de igual modo em Linux e em Windows sou valorizado... :)


"Nunca discutas com um idiota. Eles arrastam-te até ao seu nível e depois ganham-te em experiência"

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.