使用Java中的命令行工具进行通信

时间:2010-08-24 07:58:28

标签: java linux process

我想从我的Java程序中使用linux命令行工具。我启动程序并使用Process类(http://download.oracle.com/javase/6/docs/api/java/lang/Process.html)获取输出:

 /* @param args
  * @throws IOException 
  */
 public static void main(String[] args) throws IOException {
    Process proc = Runtime.getRuntime().exec("octave");

    BufferedReader reader = 
        new BufferedReader(new InputStreamReader(proc.getInputStream()));

    BufferedReader errorReader = 
        new BufferedReader(new InputStreamReader(proc.getInputStream()));

    BufferedWriter writer = 
        new BufferedWriter(new OutputStreamWriter(proc.getOutputStream()));

    int c;
    while((c = proc.getInputStream().read()) != -1) {
       System.out.print((char)c);
    }
    System.out.println("End");
 }

我得到以下输出:

  

GNU Octave,版本3.0.5版权所有   (C)2008 John W. Eaton和其他人。   这是免费软件;看到来源   复制条件的代码。有   绝对没有担保;甚至没有   A的适销性或适用性   特殊用途。有关详情,请键入   `保修”。

     

Octave配置为   “1486-PC-Linux的GNU”。

     

有关Octave的更多信息,请参阅   可在http://www.octave.org获得。

     

如果你发现这个,请提供帮助   软件很有用。欲获得更多信息,   访问   http://www.octave.org/help-wanted.html

     

报告错误(但是   首先,请阅读   http://www.octave.org/bugs.html来   学习如何撰写有用的报告。)

     

有关更改的信息   以前的版本,输入“新闻”。

奇怪的是,如果我在终端中运行八度音程,则正常输出如下:

  

:〜/ workspace / Console / src / c $ octave
  GNU Octave,3.0.5版   版权所有(C)2008 John W. Eaton等。   这是免费软件;查看复制条件的源代码。   绝对无保证;甚至没有适销性或   适用于特定用途。有关详细信息,请键入“保修”。

     

Octave配置为“i486-pc-linux-gnu”。

     

有关Octave的更多信息,请访问http://www.octave.org

     

如果您觉得此软件有用,请提供帮助。   有关详细信息,请访问http://www.octave.org/help-wanted.html

     

报告错误(但首先请阅读   http://www.octave.org/bugs.html了解如何撰写有用的报告。)

     

有关先前版本更改的信息,请键入“news”。

     

八度:1>

因此,我的输入流中不会发送请求输入的行中的字符。为什么?是否可以检测是否请求输入?

感谢您的回答!

海因里希

5 个答案:

答案 0 :(得分:7)

* nix上的程序可以检测他们是否正在与终端或其他流进行通信。许多交互式shell类型的程序在此基础上做出不同的反应(通过设置不同的提示,而不是读取一些初始化文件,甚至根本不启动)。

您可能遇到其中一种情况。

此外,也许使用Java API进行八度音阶可能更简单:例如joPAS

答案 1 :(得分:2)

由于您的问题特定于八度音阶,我建议使用--silent选项进行八度音阶并在命中行中传递所有参数。这将解决早先强调的有关启动终端会话的问题。

答案 2 :(得分:2)

你没有得到提示“octave:1>”,因为octave的输出正在被缓冲。如果输出不是交互式设备,那么在Unix / Linux上使用stdio的许多程序都会做同样的事情。在缓冲区填满(自动刷新)或缓冲区被调用fflush(3)的程序显式刷新之前,您将不会收到输出。

如果你真的想与命令行程序进行交互,那么你需要使用一个pty(因为我从来没有尝试过,所以我不知道这是不可能的。)

摘录“man stdio”,解释发生了什么:

  At  program  startup, three text streams are predefined and need not be
  opened explicitly -- standard input (for reading conventional input),
  standard  output  (for  writing conventional input), and standard error
  (for  writing  diagnostic  output).   These  streams  are   abbreviated
  stdin,stdout and stderr.  When opened, the standard error stream is not
  fully buffered;  the  standard  input  and  output  streams  are  fully
  buffered  if  and only if the streams do not to refer to an interactive
  device.

  Output streams that refer to terminal devices are always line  buffered
  by  default;  pending  output  to such streams is written automatically
  whenever an input stream that refers to a terminal device is read.   In
  cases  where  a large amount of computation is done after printing part
  of a line on an output terminal, it is necessary to fflush(3) the stan-
  dard  output  before  going  off  and computing so that the output will
  appear.

答案 3 :(得分:1)

是否可以为此提示打开新的文件描述符?

您可能会在八度音阶源代码中找到它(如果八度音程使用该代码,则为readline源代码)。

答案 4 :(得分:1)

我终于可以解决这个问题了:在Linux下,使用带有--interactive的Octave,最后使用--no-line-editing选项,它可以工作:)

海因里希