2012-01-30 73 views
4

我需要从我的Java控制台应用程序执行带有分页的less命令。但是,我发现执行外部命令的唯一方法是Runtime.getRuntime().exec(),这需要我通过流写入/读取输入/输出。所以像cat这样的命令工作(和less其实的行为就像cat),但我需要分页功能。如何通过Java控制台应用程序进行分页执行“less”?

在C中,我会使用system()。在Ruby中,Kernel.exec完成这项工作。

有什么办法可以在Java中完成这项工作吗?

回答

1

当您使用Runtime.exec()执行外部进程时,其标准输入和输出流未连接到运行Java程序的终端。你可以使用shell重定向来连接它,但首先你需要知道使用哪个终端。没有办法使用标准API来查找终端,但是可能您可以找到一个可以实现它的开源库。

地看到,这是可以做到,这个程序打开自己在less

public class Test { 
    public static void main(String[] args) throws Exception { 
     Process p = Runtime.getRuntime().exec(
       new String[] {"sh", "-c", 
       "less Test.java < "+args[0] + " > "+args[0]}); 
     System.out.println("=> "+p.waitFor()); 
    } 
} 

要运行它,你应该使用java Test $(tty)tty程序打印连接到其stdin的终端的名称。

我不太确定这个解决方案的可移植性;至少它适用于Linux。

+0

这是有趣的 - 但有没有什么办法让这个tty没有传递给它作为参数?我可以将我的工具封装在脚本中,但我宁愿避免这种情况。 – futlib 2012-01-30 22:02:25

+0

你基本上需要一个用于POSIX函数'ttyname'的JNI包装器。您可以自己创建一个或使用现有的POSIX Java库(如JPosix)(http://kanga.org/jposix/)。它有一个名为'ttyname'的方法,它将名称作为字节数组返回,没有尝试过虽然 – Joni 2012-01-31 12:52:05

+0

我已经把一个库放在github上,它本质上是'ttyname'和'isatty'的包装。仍然有点粗糙,但应该可以使用:https://github.com/joni/TTYUtil – Joni 2012-02-02 08:31:54

0

列表项

下面的程序将正常工作,首先它打印10线,然后按回车键,将打印下一行,直到文件末尾。 运行程序一样 的java减$文件名

import java.io.BufferedReader; 
import java.io.FileReader; 
import java.io.IOException; 
import java.util.Scanner; 

public class Less 
{ 


    public static void main(String args[]) throws IOException 
    { 
     FileReader reader = new FileReader(args[0]); 
     BufferedReader buff = new BufferedReader(reader); 
     String readLine; 
     int lineCount = 0; 
     while ((readLine = buff.readLine()) != null) 
     { 
      System.out.println(readLine); 
      lineCount++; 
      if (lineCount > 10) 
      { 
       Scanner scanner = new Scanner(System.in); 
       scanner.nextLine(); 
      } 
     } 
    } 
} 
相关问题