Java Program that runs commands with Linux Terminal

前端 未结 2 1287
逝去的感伤
逝去的感伤 2020-12-22 02:58

My question is this, I am running some adb commands through the terminal. I wrote a tool; that will help make things easier. So back to the question, in order to make the co

相关标签:
2条回答
  • 2020-12-22 03:48

    You "could" read the process input and when you "detect" the password prompt, display a JOptionPane and request that the user enter the password.

    You "could" prompt the user for the password before you start the process, knowing that you are going to need to send it to the process.

    You would probably still need to monitor the output of the process to determine when you need to send the password though.

    Let's start with...

    Runtime.getRuntime().exec("sudo python ./flashimage.py");
    

    You are ignoring the Process completely. Neither are you processing the output, but you have no means to provide input to the process...

    Generally, Runtime#exec is problematic at best. You are far better of using ProcessBuilder....

    // Build the command to be executed.  Note that each parameter becomes
    // it's own argument, this deals with parameters that contain spaces
    // much better then Runtime#exec alone...
    ProcessBuilder pb = new ProcessBuilder("sudo", "python", "./flashimage.py");
    pb.redirectError();
    
    InputStream is = null;
    try {
        Process p = pb.start();
        is = p.getInputStream();
        StringBuilder output = new StringBuilder(80);
        int in = -1;
        while ((in = is.read()) != -1) {
            if (in != '\n') {
                output.append((char)in);
                // You will need to define PASSWORD_PROMPT
                if (PASSWORD_PROMPT.equals(output.toString())) {
                    String text = JOptionPane.showInputDialog("Password");
                    OutputStream os = p.getOutputStream();
                    os.write(text.getBytes());
                }
            } else {
                System.out.println(output.toString());
                output.delete(0, output.length());
            }
        }
    } catch (IOException exp) {
        exp.printStackTrace();
    } finally {
        try {
            is.close();
        } catch (Exception e) {
        }
    }
    

    Now, undoubtedly, someone will point out (at least) two problems with this approach...

    1. JOptionPane.showInputDialog("Password"); will present a normal JTextField, which won't hide the password characters and
    2. String is not the safest way to to store a password...

    Instead, we should use a JPasswordField and convert the resulting char array to a byte array...

    JPasswordField password = new JPasswordField(10);
    JLabel label = new JLabel("Password: ");
    JPanel panel = new JPanel();
    panel.add(label);
    panel.add(password);
    
    int option = JOptionPane.showConfirmDialog(null, panel, "Password", JOptionPane.OK_CANCEL_OPTION);
    if (option == JOptionPane.OK_OPTION) {
        char[] userPassword = password.getPassword();
        byte[] bytes = new byte[userPassword.length * 2];
        for (int i = 0; i < userPassword.length; i++) {
            bytes[i * 2] = (byte) (userPassword[i] >> 8);
            bytes[i * 2 + 1] = (byte) userPassword[i];
        }
        os.write(bytes);
    }
    
    0 讨论(0)
  • 2020-12-22 03:57

    Child process I/O can be redirected, using Process class. You should be able to monitor the output & provide input (the password) into the child process.

    See:

    • http://docs.oracle.com/javase/7/docs/api/java/lang/Process.html
    • http://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html
    0 讨论(0)
提交回复
热议问题