How to programatically check if a software utility is installed on ubuntu using Java

前端 未结 3 1617
眼角桃花
眼角桃花 2021-01-28 23:34

I am working on a Java Project for my own learning, what i have made is a class which can both read and write to external process using Runtime.getRuntime().exec(cmd);

3条回答
  •  一个人的身影
    2021-01-28 23:51

    If you already know the name of the software binary (which is usually the same to process name) you can use which command.

    You can test it in bash/shell which firefox /usr/bin/firefox

    Also I can supply you an example written in C# of bash output reading:

    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
    }
    

    If the bash output is multi-line you can pre-filter it by piping to the grep command:

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

    EDIT 1: Reply to comments

    The major problem is the software installation, which requires "administrative" rights. I've tried to create a workaround, but the following line breaks all code:

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

    While in terminal the following command will actually attempt to install telnet (you might have to insert your user into /etc/sudoers to reproduce it on your PC).

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

    In java it will simply print (echo output) the remaining part of the command:

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

    This happens because we are simply executing /bin/echo command with a lot of parameters. I thought that it is possible to actually run the entire set of commands using bash:

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

    ..but it's not, because bash -c '..' in Java doesn't work like it should. It says that -c 'echo ...' script file can not be found, so I suppose that it misinterprets -c option. BTW I have never had this kind of problem in Mono C#.

    Here is the entire snippet:

    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());
    
        }
    }
    

提交回复
热议问题