用Java启动外部程序并将其管道化';s输出

用Java启动外部程序并将其管道化';s输出,java,Java,这可能看起来有点尴尬,但我想在Java中启动一个控制台程序,但在它自己的窗口中,同时使用tee将输出保存在日志文件中。我正在将执行此操作的程序从Perl移植到Java,并且在使用大量命令参数启动程序时遇到问题。在Perl中,它使用 system("dtterm -title $title -e /usr/bin/ksh -c \"". "cd $dir; ./$exec $arg | tee $exec.log \" &"); 我正试图使用ProcessBuilder类来做同样的事情

这可能看起来有点尴尬,但我想在Java中启动一个控制台程序,但在它自己的窗口中,同时使用tee将输出保存在日志文件中。我正在将执行此操作的程序从Perl移植到Java,并且在使用大量命令参数启动程序时遇到问题。在Perl中,它使用

system("dtterm -title $title -e /usr/bin/ksh -c \"".
"cd $dir; ./$exec $arg | tee $exec.log \" &");
我正试图使用ProcessBuilder类来做同样的事情

ProcessBuilder builder = new ProcessBuilder("dtterm", "-title", title, "-e",
"/usr/bin/ksh", "-c" "./" + exec, arg, "|", "tee", exec + ".log");
builder.directory(dir);
Process process = builder.start();
在执行此操作时,进程将启动,它不会通过管道传输到日志文件中,而是通过Perl进行传输。我尝试过使用builder.getInputStream()方法,但由于它显示在dtterm窗口中,因此out进程没有输出

我需要有单独的窗口,因为程序同时启动几个不同的程序,每个程序都有自己的窗口。我确实尝试过直接启动它,并将所有进程的输出发送到我的程序stdout,但是太多了,需要单独保存。如果没有办法这样做,那么我将不得不制作一个JFrame来显示程序输出,但如果可能的话,我希望避免这样做


谢谢

您需要以不同的方式构建您的命令。你想要的是:

dtterm -title <title> -e /usr/bin/ksh -c "./<exec> arg | tee <exec>.log"

是的,这看起来很难看,你必须小心正确地转义
exec
,以防它包含空格或引号之类的特殊字符。

谢谢,这不太管用,但让我找到了它。与您的一样,在-c之后的所有内容都需要在1个串联字符串中,但它不需要字符串中的引号。我不知道为什么会这样,但我在另一个进程中注意到了这一点,在这个进程中,我指定了一个标题,我有了新的ProcessBuilder(“exec”、“-title”、“\“Program title\”),标题显示在“在上面。把它们拿出来,它仍然有效。也许java在字符串中保留了所有的1个agument dispite空格。当然,你是对的。Java负责确保将一个参数作为单个参数传递给程序,不需要引号。不过,您仍然需要转义特殊字符。:)
ProcessBuilder builder = new ProcessBuilder("dtterm", "-title", title, "-e", "/usr/bin/ksh", "-c", "./" + exec + " arg + " | tee " + exec + ".log");