Runtime.getRuntime()。exec(“ C:\ cygwin \ bin \ bash.exe”)没有要读取的输入

【字号: 日期:2024-03-01浏览:28作者:雯心
如何解决Runtime.getRuntime()。exec(“ C:\ cygwin \ bin \ bash.exe”)没有要读取的输入?

就Java而言,据我所知,仅当它作为脚本运行时,才可以通过管道将bash的输出(或输入)通过管道传递给bash,而不是当它作为交互式shell运行时(在这种情况下,只能将cmd参数传递给它)。

换句话说,如注释中所述,当您从cmd运行bash时,您会看到输出,但它包含在bash进程中,bash发送回父cmd进程不是输出。

关于javac进程,它实际上是将输出发送到错误流。尝试从CMD运行javac 1>null和javac 2>null,你会看到其中的差别。您看过这里的api吗?您可以尝试使用ProcessBuilder并将错误流重定向回主要输入流,以这种方式处理流程会容易得多。

解决方法

我正在尝试执行一个新流程,并从Java中的输入流中读取内容。我已经成功使用Runtime.getRuntime()。exec(String)来启动和接收来自多个进程的输入。但是,当我尝试在其他某些进程上使用exec时,输入流的read方法将阻塞,并且似乎没有输入。是什么原因导致其中某些过程的输入流为空?具体来说,我想知道为什么bash.exe没有输出任何内容。

我已经编写了一个JUnit测试用例来演示此问题:

import java.io.IOException;import java.io.InputStream;import java.util.ArrayList;import java.util.Arrays;import java.util.List;import junit.framework.TestCase;public class TestExec extends TestCase { public void testExec() throws IOException {List<InputPrinter> threads = new ArrayList<InputPrinter>();// Create a process for each of the commands and make sure that// it outputs at least one line to its input stream.threads.add(testExec('cmd'));threads.add(testExec('java'));threads.add(testExec('C:/cygwin/bin/vim-nox.exe'));// These bottom two fail,even though executing these// commands in cmd.exe results in immediate outputthreads.add(testExec('javac'));threads.add(testExec('C:/cygwin/bin/bash.exe'));// Give the threads a second to executetry { Thread.sleep(1000);} catch (InterruptedException e) { e.printStackTrace(); fail();}// Test that each command had input to readfor(InputPrinter ip : threads) { assertTrue(ip.command + ' has not read any input',ip.hasRead);} } // Starts a process for the given command and returns an // InputPrinter that can be used to check if the process // has had an input to read. public InputPrinter testExec(String command) throws IOException {Process proc = Runtime.getRuntime().exec(command);InputStream in = proc.getInputStream();InputPrinter ip = new InputPrinter(in,command);new Thread(ip).start();return ip; } // Simple Runnable to read from an InputStream. hasRead will be // true if at least one input has been read from the stream private class InputPrinter implements Runnable {InputStream in;String command;boolean hasRead;public InputPrinter(InputStream in,String command) { this.in = in; this.command = command; this.hasRead = false;}// Loop indefinitely while printing any received inputpublic void run() { try {final byte[] b = new byte[1024];while (true) { int n = in.read(b); if (n > 0) {System.out.print(new String(Arrays.copyOf(b,n)));hasRead = true; }} } catch (IOException e) {e.printStackTrace();fail(); }} }}

编辑:

据我所知,如果程序未使用stdout或stderr,则Windows命令提示符下不会显示任何内容。启动bash进程时,我期望看到的是“ bash-3.2$”,这与打开命令提示符并运行“ bash.exe”时看到的相同:

Microsoft Windows [Version 6.1.7600]Copyright (c) 2009 Microsoft Corporation. All rights reserved.C:cygwinbin>bash.exebash-3.2$

相关文章: