运行 使用 java 的 perl 脚本

run a perl script using java

我有一个文件 lowercase.perl ,它将一个文件作为输入并将其所有内容以小写形式打印到另一个输出文件中。

use warnings;
use strict;

binmode(STDIN, ":utf8");
binmode(STDOUT, ":utf8");

while(<STDIN>) {
  print lc($_);
   }

我想 运行 从 java

import java.io.*;

public class Sample {
    public static void main(String args[]) {
        Process process;
        try
        {
            process = Runtime.getRuntime().exec("perl lowercase.perl  <lower.eng> lowerlm.eng");

            process.waitFor();
            if(process.exitValue() == 0)
            {
                System.out.println("Command Successful");
            }
            else
            {
                System.out.println("Command Failure");
            }
        }
        catch(Exception e)
        {
            System.out.println("Exception: "+ e.toString());
        }
    }
}

但这不起作用。 我的所有文件都在同一个目录中,我 运行ning 终端也在同一个目录中。似乎正在发生的事情是正在执行 perl 脚本,但是我传递的输入参数 <lower.eng>(必须使用菱形运算符传递)无法正常工作. 我直接有 运行 perl 脚本,如果 运行 不使用 java.

它工作正常

你的描述有点混乱的地方是

exec("perl lowercase.perl  <lower.eng> lowerlm.eng");

... the input parameter <lower.eng> (this has to be passed with diamond operators) that i have passed is not working properly.

因为这意味着您希望将文字字符串 "<lower.eng>" 作为命令行参数。然而,在你的评论中你说

lowerlm.eng gets edited with the lowercase version of all the text from lower.eng this happens only when perl command is ran directly but not when ran using java

也就是说<lower.eng>lowerlm.eng实际上是shell redirections. Although not explicitly stated in the documentation of Runtime.exec,看来Java并没有调用shell。 事实上,如果在您的 Perl 脚本中检查 @ARGV(例如,通过将其写入文件),您将看到当从 Java 调用时,您的 Perl 脚本是通过命令行调用的参数 "<lower.eng>""lowerlm.eng" 而不是重定向其输入和输出。

有几个可能的解决方案:

A.直接用Java的ProcessBuilder to set up the redirections for you, either to and from files, or, if your input and/or output originates in the same Java program, avoid the temporary files using OutputStream and InputStream。这不需要对 Perl 脚本进行任何修改。

ProcessBuilder pb = new ProcessBuilder("perl", "lowercase.perl");
pb.redirectInput(new File("lower.eng"));
pb.redirectOutput(new File("lowerlm.eng"));
Process process = pb.start();

B. 修改 Perl 脚本以在命令行上接受 input/output 文件名(例如 Getopt::Long,尽管下面我将其保持更简单) , 这样您就不必依赖 shell 重定向。

use warnings;
use strict;

die "Usage: [=12=] INFILE OUTFILE\n" unless @ARGV==2;
my $INFILE  = $ARGV[0];
my $OUTFILE = $ARGV[1];

open my $ifh, '<', $INFILE  or die "$INFILE: $!";
open my $ofh, '>', $OUTFILE or die "$OUTFILE: $!";
while (<$ifh>) {
    print $ofh lc;
}
close $ifh;
close $ofh;

C.虽然我不推荐这个,只是为了完整起见:你可以调用shell 来自 Java,例如sh -c 'perl ...'。这不是一个好主意,因为您必须 非常 小心引用和所有 shell 元字符。