使用 Linux 终端运行命令的 Java 程序

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

最佳答案

您“可以”读取流程输入,当您“检测”到密码提示时,显示一个 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 不是存储密码的最安全方式...

相反,我们应该使用 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);
}

关于使用 Linux 终端运行命令的 Java 程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18838904/

相关文章:

java - 如何使用 ClassLoader 或 Class 以编程方式加载类

java - 在编译时,JVM 如何发现不必要的 CloneNotSupportedException 而不是 Exception?

.net - 性能关键的 GUI 应用程序(windows、linux)

python - 将带空格的参数传递给 linux 服务

linux - Alsa 无法设置样本格式[FFMPEG]

保留输出的终端调整大小

java - 使用 preparedStatement 设置 mysql 主键字段时出错

java - 0.05 结果显示 4 便士而不是 1 镍币

终端应用程序上的 Cocoa UI

node.js - 安装后如何执行 'coffee'命令?