有两个 Linux 命令行程序(whiptail和dialog)提供向用户显示文本 UI 的能力。我想从我的 Java 应用程序中调用其中一个(最好是whiptail),以便用户可以从预定义的列表中选择一个选项。以下 SO 问题对我了解如何从我的代码中调用 Linux 命令很有帮助:
这些提供了有关如何运行典型 Linux 命令(例如“ls”)的有用提示,但由于我希望向用户显示文本 UI,我的情况有点复杂(我认为)。
要了解whiptail 的作用和外观,请参见this。
开始ProcessBuilder
。您要发送命令的每个参数都是命令列表中的一个单独元素,例如...
import java.io.IOException;
import java.io.InputStream;
public class Test {
public static void main(String[] args) throws IOException, InterruptedException {
ProcessBuilder pb = new ProcessBuilder(
"whiptail", "--title", "Check list example", " --checklist",
"Choose user's permissions", "20", "78", "4",
"NET_OUTBOUND", "Allow connections to other hosts", "ON",
"NET_INBOUND", "Allow connections from other hosts", "OFF",
"LOCAL_MOUNT", "Allow mounting of local devices", "OFF",
"REMOTE_MOUNT", "Allow mounting of remote devices", "OFF");
pb.redirectInput(Redirect.INHERIT);
// I tend to use pb.redirectErrorStream(true);
// which sends the error stream to the input stream, but
// then you'd need to still consume it to get the result
Process p = pb.start();
InputStreamConsumer errorConsumer = new InputStreamConsumer(p.getErrorStream());
Scanner input = new Scanner(System.in);
String option = input.nextLine();
p.getOutputStream().write(option.getBytes());
p.getOutputStream().flush();
int exitCode = p.waitFor();
System.out.println(exitCode);
errorConsumer.join();
System.out.println(errorConsumer.getContent());
}
public static class InputStreamConsumer extends Thread {
private InputStream is;
private StringBuilder content;
public InputStreamConsumer(InputStream is) {
this.is = is;
content = new StringBuilder(128);
}
public String getContent() {
return content.toString();
}
@Override
public void run() {
try {
int value = -1;
while ((value = is.read()) != -1) {
content.append((char)value);
}
} catch (IOException exp) {
exp.printStackTrace();
}
}
}
}
这是非常基本的,它只是执行命令,将它的输出消耗到一个StringBuilder
(稍后检索),等到命令存在并显示基本结果。
由于我无权访问whiptail
,我无法测试代码,但如果该命令在操作系统的默认搜索路径中可用,它应该可以工作,否则您需要提供该命令的路径作为一部分命令列表中的第一个元素