2011-12-13 122 views
0

我在一个Java项目的工作为我自己学习的Ubuntu的软件工具,有什么我已经是一类可以读取和使用写入外部进程Runtime.getRuntime().exec(cmd);如何以编程方式检查是否安装使用Java

现在我想知道是否有任何特殊的方法来检查系统上是否安装了特定的软件/工具。

就像我使用sshpass实用程序来远程登录到其他机器,如果它不是已经存在,我想用我的程序安装它。但是,对于这个我应该如何去检查它是否存在或不存在?

我脑海中的想法是运行该命令并查看响应,如果返回的字符串匹配特定的表达式,则基于该信息我会判定它是存在还是不存在。

你认为这是正确的方法还是有任何其他方式来找出这个?

就像在Windows中,我认为有像FTYPE,assoc命令等CMDLINE公用事业, 谢谢,

回答

1

如果您已经知道软件二进制文件的名称(通常与进程名称相同),则可以使用which命令。

您可以在bash测试/壳 其中火狐 在/ usr/bin中/火狐

此外,我可以为您提供写在bash输出读数的C#示例:

字符串输出=字符串。空的;

string output = string.Empty; 

try 
{ 
    // Sets up our process, the first argument is the command 
    // and the second holds the arguments passed to the command 
    ProcessStartInfo ps = new ProcessStartInfo("bash"); 
    ps.Arguments = "-c 'firefox'"; 
    ps.UseShellExecute = false; 

    // Redirects the standard output so it reads internally in out program 
    ps.RedirectStandardOutput = true; 

    // Starts the process 
    using (Process p = Process.Start(ps)) 
    { 
     // Reads the output to a string 
     output = p.StandardOutput.ReadToEnd(); 

     // Waits for the process to exit must come *after* StandardOutput is "empty" 
     // so that we don't deadlock because the intermediate kernel pipe is full. 
     p.WaitForExit(); 
    } 
} 
catch 
{ 
    // TODO manage errors 
} 

如果bash的输出是多行的管道,你可以预先筛选它grep命令:

ps.Arguments = "-c 'cpuid | grep MySearchTerm'"; 

编辑1:回复评论

的主要问题是需要“管理”权限的软件安装。 我试图创建一个解决办法,但下面的行打破了所有代码:

process = Runtime.getRuntime().exec(new String[]{"/bin/bash","-c","'echo RIadminXsrv1 | sudo -S apt-get install telnet -qy'"}); 

而在终端以下命令将实际尝试安装远程登录(你可能需要用户插入/etc/sudoers重现它在你的电脑上)。

/bin/echo myUserPass | /usr/bin/sudo -S /usr/bin/apt-get install telnet -qy

在java中它会简单地打印(echo输出)命令的剩余部分:

myUserPass | /usr/bin/sudo -S /usr/bin/apt-get install telnet -qy

这是因为我们只是执行了大量的参数/bin/echo命令。 我认为这是可能的实际运行整套使用bash命令的:

bash -c '/bin/echo myUserPass | /usr/bin/sudo -S /usr/bin/apt-get install telnet -qy' 

..但它不是,因为bash -c '..'在Java中并不像它应该工作。它说-c'echo ...'脚本文件无法找到,所以我想它误解了-c选项。 顺便说一句,我从来没有在单声道C#这种问题。

这里是整个片段:

package javaapplication1; 

import java.io.*; 

public class JavaApplication1 { 

    public static void main(String[] args) { 

     Process process; 
     String softwareToCheck = "telnet"; // Change here 

     try 
     {  
      if(!_softwareExists(softwareToCheck)) 
      { 
       System.out.println("Installing missing software.."); 
       process = Runtime.getRuntime().exec(new String[]{"/bin/bash","-c","'echo RIadminXsrv1 | sudo -S apt-get install telnet -qy'"}); 

       try 
       { 
        process.waitFor(); 
       } 
       catch(InterruptedException e) 
       { 
        System.out.println(e.getMessage()); 
       } 

       if(!_softwareExists(softwareToCheck)) 
       { 
        System.out.println("Software is still missing!"); 
       } 

      } 
      else 
      { 
       System.out.println("Software is installed!"); 
      } 
     } 
     catch(IOException e) 
     { 
      System.out.println(e.getMessage()); 
     }   
    } 

    private static boolean _softwareExists(String binaryName) throws IOException 
    { 
     String line; 
     ProcessBuilder builder; 
     BufferedReader reader; 
     Process process; 

     builder = new ProcessBuilder("/usr/bin/which", binaryName); 
     builder.redirectErrorStream(true); 
     process = builder.start(); 
     reader = new BufferedReader(new InputStreamReader(process.getInputStream())); 
     try 
     { 
      process.waitFor(); 
     } 
     catch(InterruptedException e) { 
      System.out.println(e.getMessage()); 
     } 

     while ((line = reader.readLine()) != null) 
     { 
      break; // Reads only the first line 
     } 

     return (line != null && !line.isEmpty()); 

    } 
} 
+0

我知道如何读/写过程,但你能告诉我如何检查像ssh这样的工具吗? – Johnydep

+0

..但是_softwareExists(String binaryName)函数对于请求的第一部分是可以的。 – Salaros

+0

感谢您的答案 – Johnydep

2

在Ubuntu的/ Debian的你可以使用:

dpkg -s packagname 

,看看是否已安装包。然后,您可以在应用程序中解析该命令的输出。

+0

感谢,它工作得很好软件包e.g火狐等,但像SSH公用事业,sshpass我总是得到相同的响应,它没有安装,尽管它们在系统中安装? – Johnydep

0

,我不知道有任何工具,可以帮助,如果包管理工具不正确报告安装的。可能是某些工具已安装,但未更新数据库。

检查您的目标可执行文件是否存在于$ PATH和标准位置的任何目录中可能很有用。

String pathString = System.getenv("PATH"); 
    String[] dirs= pathString.split(':'); 
    String[] exes= { "name1", "name2" ....}; 

    for (String exename : exes) { 
    for (String dirname : dirs) { 
      File exeFile=new File(dirname, exename); 
      //do some checks if file exists etc. 
    } 
    } 
相关问题