Java获得bash root访问权限

时间:2016-01-08 20:29:52

标签: java linux root sudo

我正在尝试在Linux上为我正在制作的程序安装缺少的依赖项。但是,我无法获得安装缺少的依赖项所需的root访问权限。以下是我到目前为止的情况:

我的逻辑如下:

1)检查是否使用pacapt安装了依赖项(在本例中为npm) 2)如果是,则使用文本提示获取用户密码 3)然后继续进一步说明:echo [userpass] | sudo -S ......

现在'echo [userpass] | sudo -S ...'命令就像这样打印到shell; [userpass] | sudo -S ...(显示用户密码代替[userpass]),但不执行。

这是我的代码:

public class LinuxDependencyCheck extends Application{
    public static void main (String [] args){
            launch(args);
    }

    @Override
    public void start(Stage mainWindow){

            String userPass = null;
            String terminalOut = null;

            terminalOut = runBash("./LinuxScripts/pacapt -Qqe npm");

            if (terminalOut.equals("npm")){
                    userPass = getUserPass();
                    if (userPass != null){
                            System.out.println("runing");
                            runBash("echo " + userPass + " | sudo -S npm install" + 
                                            " phantomjs2");
                    }
            }

    }

    public String runBash(String runCommand){
            String result = null;
            String returnVal = null;
            try {
                    Runtime r = Runtime.getRuntime();                    

                    Process p = r.exec(runCommand);

                    BufferedReader in =
                            new BufferedReader(new InputStreamReader(p.getInputStream()));
                    String inputLine;
                    while ((inputLine = in.readLine()) != null) {
                            System.out.println(inputLine);
                            result += inputLine;
                            returnVal = inputLine;
                    }
                    in.close();

            } catch (IOException e) {
                    System.out.println(e);
            }

            return returnVal;
    }

    public String getUserPass(){
            TextInputDialog dialog = new TextInputDialog("Password");
            dialog.setTitle("Installation helper");
            dialog.setHeaderText("It looks like you are missing" + 
                            " dependecies to complete this action" + 
                            " would you like to try to install" +
                            " them now");
            dialog.setContentText("Please enter your password :");

            // Traditional way to get the response value.
            Optional<String> result = dialog.showAndWait();
            if (result.isPresent()){
                    return result.get().toString();
            }
            return result.get();
    }
}

1 个答案:

答案 0 :(得分:0)

您的runBash()方法命名不佳,因为它不会导致给定命令通过bash运行。因此,使用命令字符串也是不合适的,例如您指定的命令字符串,它依赖于shell的管道操作符将两个单独的命令串在一起。

当你这样做时......

runBash("echo " + userPass + " | sudo -S npm install" + 
                                            " phantomjs2");

... Java在空格上拆分字符串,将第一个子串(“echo”)作为命令,并以所有其他子串字符串作为参数执行该命令。毋庸置疑,这将毫无错误地运行,但也没有你想要的效果。

如果你真的想通过bash执行命令字符串(就像你看到的那样),那么在runBash()方法中你可以改变它......

                Process p = r.exec(runCommand);

......对此...

                Process p = r.exec("/bin/bash", "-c", runCommand);

。这至少应该让你超越你的第一道障碍。

您还应该关闭Process的{​​{1}}(您可以将管道数据导入流程),并排除OutputStream的错误流。通常,您需要并行排空输入和错误流,因为如果任何一个缓冲区填满,则进程可能会阻塞。也许这不是这个特定命令的风险,但你需要判断。它也是Process waitFor()的良好形式;这样做可以避免Java累积僵尸子进程。