我使用java.lang.Process来执行shell脚本,它需要用户交互输入。在Java中,我无法获得请求用户输入的提示消息。
在这个例子中,我想得到**“输入你的名字:“**在Java进程中执行。
read -p 'Enter your name: ' name;
echo "Hello, $name!"
我尝试通过Process InputStream和ErrorStream获取shell脚本输出。他们只能得到回声输出。
此代码仅打印
outputFuture:你好,myName!
ProcessBuilder pb = new ProcessBuilder("/bin/bash", "-c", "read -p 'Enter your name: ' name; echo \"Hello, $name!\"");
Process process = pb.start();
InputStream is = process.getInputStream();
InputStream es = process.getErrorStream();
// Create a separate thread to read the output of the process
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> outputFuture = executor.submit(() -> {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line;
while ((line = reader.readLine()) != null) {
return line;
}
return null;
});
//Input myName to continue shell script
OutputStream os = process.getOutputStream();
os.write("myName\n".getBytes());
os.flush();
Thread.sleep(1000);
//Reading ErrorStream
BufferedReader reader = new BufferedReader(new InputStreamReader(es));
String line;
while ((line = reader.readLine()) != null) {
LOGGER.info("error reader: {}", line);
}
int exitCode = process.waitFor();
LOGGER.info("Script exited with code " + exitCode);
// Display the output of the process
String output = outputFuture.get();
if (output != null) {
LOGGER.info("outputFuture: {}", output);
}
executor.shutdown();
2条答案
按热度按时间42fyovps1#
read
的-p
参数仅在stdin附加到终端时才有效。引用shell的源代码:你可以将bash的副本 Package 在类似
unbuffer
的东西中,以模拟TTY(ProcessBuilder("/usr/bin/unbuffer", "/bin/bash", "-c",
...),但我通常建议首先不要依赖-p
(这是有原因的,被编程调用的工具通常通过环境变量或命令行接受参数)。qlfbtfca2#
看起来bash内置调用
read
并没有写入stdout或stderr,也许它写入了自己的控制台。Java也看不到。您可以在bash
shell中运行以下命令进行确认:如果您想看到输出的消息,您可以更改命令以使用
echo
或echo -n
,这样提示符会首先出现。您可以使用以下命令捕获所有stdout行:
请注意,如果您期望stdin更大,则需要更多线程(stdout和stderr消费者各一个),或者保留一个后台线程并使其读取组合的stdout+stderr - add
pb.redirectErrorStream(true)
。