【问题标题】:Java program is not able to execute terminal commandJava程序无法执行终端命令
【发布时间】:2015-12-17 02:24:42
【问题描述】:
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 程序无法创建它。

这个程序无法创建 services.txt 文件,我根本没有收到任何错误,所以我很困惑是什么问题。你能帮我找出问题吗?谢谢你。

【问题讨论】:

  • 您是否只需要 services.txt 来将数据从命令输出传递到您的 Java 程序?最好使用 p.getInputStream() 或 p.getErrorStream() 代替
  • 强烈建议使用完整路径名 (/bin/ps),因为不支持 PATH 设置。重定向也不起作用。 ProcessBuilder 类提供了读取或重定向程序输出的方法。
  • 1.不要使用 Runtime.exec(),使用 ProcessBuilder。 2. 它们中的任何一个都不会在 shell 解释器中发出命令,这就是为什么你的命令不起作用(>> xxx 由命令解释器解释;但这里这些是ps 命令的参数,其中当然,对他们一无所知。)。

标签: java ubuntu terminal


【解决方案1】:

这会调用一个子进程而不依赖任何 shell 机制,捕获生成的标准输出。

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 ){

}

【讨论】:

  • 呃,不是重新抛出错误?另外,为什么不使用 try-with-resources?
  • 不,但是现在是 2015 年,try-with-resources 已经与我们合作了 4 年
【解决方案2】:

Inu如果您的命令返回非零退出代码(通常表示失败),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();
            }

        }
    }
}

【讨论】:

  • AutoStart.java:29: error: incompatible types: OutputStream cannot be converted to InputStream 在这行br = new BufferedReader(new InputStreamReader(p.getOutputStream()));
  • @user3774654 我的错误,当我的意思是getInputStream()时不小心放了getOutputStream()。我修复了我的帖子。
猜你喜欢
  • 2018-08-21
  • 2014-12-15
  • 2017-06-28
  • 2015-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-29
  • 2020-07-24
相关资源
最近更新 更多