如何以编程方式检查是否在使用Java的ubuntu上安装了软件实用程序

我正在为自己的学习开发Java项目,我所做的是一个可以使用Runtime.getRuntime().exec(cmd);读写外部进程的类Runtime.getRuntime().exec(cmd);

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

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

我在脑海中的想法是运行命令并查看响应,如果返回的字符串与特定表达式匹配,则基于我将决定它是否存在。

你认为这是正确的方法还是有其他方法可以找到这个?

就像在Windows上,我认为有像ftype,assoc等cmdline实用程序,谢谢你,

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

你可以在bash / shell中用firefox / usr / bin / firefox测试它

另外,我可以为您提供一个用B#输出读取的C#编写的示例:

string output = string.Empty;

 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'"}); 

在终端中,以下命令实际上将尝试安装telnet(您可能必须将用户插入/ etc / sudoers以在PC上重现它)。

/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中的bash -c '..'不能像它应该的那样工作。 它说无法找到-c’echo …’脚本文件,所以我认为它误解了-c选项。 顺便说一下,我从未在Mono 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()); } } 

在Ubuntu / Debian中你可以使用:

 dpkg -s packagname 

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

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

检查目标可执行文件是否存在于$ 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. } }