2015-09-20 5 views
1
import java.io.*; 
import java.io.IOException; 
import java.util.Scanner; 

public class AutoStart{ 
    public static void main(String[] args){ 
     while(true){ 
      Runtime r = Runtime.getRuntime(); 
      try{ 
       Process p = r.exec("ps -ef >> services.txt"); 
       try{ 
        p.waitFor(); 
       } catch(InterruptedException e){ 
        e.getStackTrace(); 
       } 

       Scanner txtscan = new Scanner(new File("services.txt")); 
       int running = 0; //0 means not running and 1 means running 
       while(txtscan.hasNextLine()){ 
        String str = txtscan.nextLine(); 
        if(str.indexOf("red5") != -1){ 
         running = 1; 
        } 
       } 

       if(running == 0){ 
        //red5 is not running so start it now 
        //code to start it goes here 
       } 

       //at the end remove services.txt file 
       //code to remove that file goes here. 


      } catch(IOException e){ 
       e.getStackTrace(); 
      } 

      try { 
       Thread.sleep(1000);     //1000 milliseconds is one second. 
      } catch(InterruptedException ex) { 
       Thread.currentThread().interrupt(); 
      } 

     } 
    } 
} 

В строке 10 Я пытаюсь создать текстовый файл, содержащий список всех запущенных программ, но моя java-программа не может его создать.Программа Java не может выполнять команду терминала

Эта программа не может создать файл services.txt, и я не получаю никакой ошибки, поэтому я смущен в чем проблема. Можете ли вы помочь мне разобраться с проблемой? Спасибо.

+0

Вам нужны только services.txt, чтобы передавать данные из вывода команды в вашу программу Java? Лучше использовать p.getInputStream() или p.getErrorStream() вместо –

+0

Настоятельно рекомендуется использовать полное имя пути (/ bin/ps), поскольку настройка PATH не выполняется. Перенаправление тоже не будет работать. Класс ProcessBuilder предоставляет способы чтения или перенаправления вывода программы. – laune

+1

1. Не используйте Runtime.exec(), используйте ProcessBuilder. 2. либо один из них НЕ выдаст команду в интерпретаторе оболочки, поэтому ваша команда не будет работать ('>> xxx' интерпретируется интерпретатором команд, но здесь это аргументы команды' ps', которая , конечно, ничего не знает о них.). – fge

ответ

1

Это вызывает подпроцесс, не полагаясь на любой механизм оболочки, ловя полученный стандартный вывод.

public static void main(String[] args) throws Exception { 
    try { 
    ProcessBuilder pb = new ProcessBuilder("/bin/ps", "-ef"); 
    Process process = pb.start(); 
    InputStream is = process.getInputStream(); 
    Reader rdr = new InputStreamReader(is); 
    LineNumberReader lnr = new LineNumberReader(rdr); 
    String line; 
    while((line = lnr.readLine()) != null){ 
     if(line.contains("skype")){ 
     System.out.println("skype is running"); 
     } 
    } 
    process.waitFor(); 
    } catch(Exception e){ 

    } catch(Error e){ 

} 
+0

Спасибо. Это сработало отлично :) – user3774654

+0

Эт, а не повторные ошибки? Кроме того, почему бы вам не использовать try-in-resources? – fge

+0

@fge Я должен делать всю работу? – laune

1

InuThe Process класс не будет генерировать исключение, если ваша команда возвращает ненулевой код выхода (обычно указывает на сбой). Вы должны вникать в него сами.

Ниже приведено базовое изменение вашего кода, на котором будет выводиться сообщение об ошибке и выходном потоке (инструменты командной строки могут печатать на) в консоли после получения ненулевого кода выхода из процесса.

Надеюсь, это поможет вам понять это:

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

public class AutoStart{ 
    public static void main(String[] args){ 
     while(true){ 
      Runtime r = Runtime.getRuntime(); 
      try{ 
       Process p = r.exec("ps -ef >> services.txt"); 
       try{ 
        p.waitFor(); 
       } catch(InterruptedException e){ 
        e.getStackTrace(); 
       } 

       if (p.exitValue() != 0){ 

        BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream())); 

        System.out.println("Error Stream:"); 

        String line; 

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

        br = new BufferedReader(new InputStreamReader(p.getInputStream())); 

        System.out.println("Output Stream:"); 

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

        System.exit(1); 
       } 

       Scanner txtscan = new Scanner(new File("services.txt")); 
       int running = 0; //0 means not running and 1 means running 
       while(txtscan.hasNextLine()){ 
        String str = txtscan.nextLine(); 
        if(str.indexOf("red5") != -1){ 
         running = 1; 
        } 
       } 

       if(running == 0){ 
        //red5 is not running so start it now 
        //code to start it goes here 
       } 

       //at the end remove services.txt file 
       //code to remove that file goes here. 


      } catch(IOException e){ 
       e.getStackTrace(); 
      } 

      try { 
       Thread.sleep(1000);     //1000 milliseconds is one second. 
      } catch(InterruptedException ex) { 
       Thread.currentThread().interrupt(); 
      } 

     } 
    } 
} 
+0

'AutoStart.java:29: ошибка: несовместимые типы: OutputStream не могут быть преобразованы в InputStream' В этой строке ' уш = новый BufferedReader (новый InputStreamReader (p.getOutputStream())); ' – user3774654

+0

@ user3774654 Моя ошибка, случайно положил 'getOutputStream()' когда я имел в виду, 'getInputStream()'. Я исправил свой пост. – Ownaginatious