使用Linux Terminal运行命令的Java程序

时间:2013-09-16 23:19:03

标签: java linux terminal

我的问题是,我正在通过终端运行一些adb命令。我写了一个工具;这将有助于使事情变得更容易。所以回到问题,为了使命令运行,我必须在终端上输入“密码”。那么我该怎么做才能使“密码”部分出现在JOptionPane.showInputDialog框中呢?

这是我到目前为止所做的:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;

import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileNameExtensionFilter;


public class flash implements ActionListener {
    private File runfile;
    @Override
    public void actionPerformed(ActionEvent arg0) {
        {


            JFileChooser adbflashfile = new JFileChooser("/home/local/ANT/arthm/Desktop/os"); 
           FileNameExtensionFilter filter = new FileNameExtensionFilter(".py", "py");

                adbflashfile.setFileFilter(filter);

            int returnVal = adbflashfile.showOpenDialog(null);
            if (returnVal == JFileChooser.APPROVE_OPTION) {
                runfile = adbflashfile.getSelectedFile();

                try {
                    Runtime.getRuntime().exec("sudo python ./flashimage.py");
                } catch (IOException e1) {

                    e1.printStackTrace();
                }
                //This is where a real application would open the file.
                System.out.println("File: " + runfile.getName() + ".");    
            } else {
                JOptionPane.showMessageDialog(null, "Open command cancelled by user.");
            }
            System.out.println(returnVal);
        }
    };
    }

2 个答案:

答案 0 :(得分:1)

你"可以"阅读过程输入,当你"检测"密码提示,显示JOptionPane并请求用户输入密码。

你"可以"在开始流程之前提示用户输入密码,因为他知道您需要将密码发送到流程。

您可能仍需要监控进程的输出,以确定何时需要发送密码。

让我们开始......

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

您完全忽略了Process。您既没有处理输出,也没有办法为流程提供输入......

通常,Runtime#exec充其量只是个问题。你更善于使用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) {
    }
}

现在,毫无疑问,有人会指出(至少)这种方法存在两个问题......

  1. JOptionPane.showInputDialog("Password");会显示正常JTextField,但不会隐藏密码字符和
  2. String不是存储密码最安全的方法......
  3. 相反,我们应该使用JPasswordField并将生成的char数组转换为byte数组...

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

答案 1 :(得分:0)

可以使用Process类重定向子进程I / O.你应该能够监控输出和输出。提供输入(密码)到子进程。

见: