【问题标题】:Running Perl-Script from Java (embedded in Perl)从 Java 运行 Perl 脚本(嵌入在 Perl 中)
【发布时间】:2011-11-02 08:05:57
【问题描述】:

Perl 通过 STDIN 接受 scipt。按下 CTRL-D 后 perl 知道“脚本结束”。完成后,脚本被执行。

现在我的问题是:我想从 Java 中做到这一点。

  1. 打开进程 Perl
  2. 将脚本复制到 Perl 进程的 STDIN 中
  3. 如何在不关闭流的情况下向 PERL CRTL-D 发出信号(来自 在java中)
  4. 向脚本发送一些输入
  5. 从脚本中获取一些输出。

proc = Runtime.getRuntime().exec("perl", env);
commandChannel = new BufferedWriter(new OutputStreamWriter(proc.getOutputStream()));
responseChannel = new BufferedReader(new InputStreamReader(proc.getInputStream()));
InputStreamReader mymacro = new InputStreamReader(getClass().getResourceAsStream("macro.perl"));

char[] b = new char[1024];
int read;

try
{
    while ((read = mymacro.read(b)) != -1)
    {
        commandChannel.write(b, 0, read);
    }
    commandChannel.flush();
    PERL IS WAITING FOR END OF SCRIPT; ??
}  ...

【问题讨论】:

  • 如果您将__END__ 写入 Perl 而不是关闭 STDIN,会发生什么? (或^D^Z——见perldoc.perl.org/perldata.html#Special-Literals
  • 我不知道为什么,但是对于一个小脚本它可以工作,但对于我的大脚本不是......我想我会将脚本写入一个临时文件并加载它......

标签: java perl pipe eof


【解决方案1】:

但这正是 CTRL-D 所做的:关闭进程的 STDIN。因此,在您的情况下,关闭 proc.getInputStream() 是在 shell 中模拟它时具有预期行为的适当操作。

如果你想做“其他事情”,那就去做吧。就像通过 STDIN 向您的脚本编写一个特殊命令,然后将其解释为这样并跳转到另一个状态或任何所需的状态

【讨论】:

  • 但是当我关闭输出流(到我的脚本的标准输入)时,我不能再使用它了。在 Shell 中是可能的。运行 perl。输入 als Script $line=<STDIN>; print $line; 然后 CTRL-D ... 现在脚本运行并可以回显您的输入
  • 嗯,我的java知识有点生疏,但是当您说OutputStream时,您是指proc.getOutputStream()还是getInputStream()?因为我认为 getInputStream 是您流程的标准输入。
  • 确保在您的脚本中 .write 一个“\n”(换行符)。这将使 $line= 不再阻塞。
  • 我试图通过“perl FILENAME”运行脚本......现在我想将脚本嵌入到 jar 文件中并通过 stdin 将其传输到 perl ...
【解决方案2】:

这个例子正是你需要的:

public class TestPl {
public static void main(String[] args) {
  Process proc;
  try {
     proc = Runtime.getRuntime().exec("perl");
     // a simple script that echos stdin.
     String script = "my $s=<>;\n" +
                     "print $s;";

     OutputStreamWriter wr = new OutputStreamWriter(proc.getOutputStream());

     //write the script:
     wr.write(script);

     //signal end of script:
     wr.write(4);
     wr.write("\n");

     //write the input:
     wr.write("bla bla bla!!!");

     wr.flush();
     wr.close();

     String output = readFromInputStream(proc.getInputStream());
     proc.waitFor(); 
     System.out.println("perl output:\n"+output);
  } catch (IOException e) {
     e.printStackTrace();
  } catch (InterruptedException e) {
     e.printStackTrace();
  }
}

public static String readFromInputStream(InputStream inputStream) throws IOException {
  BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
  String line;
  StringBuffer buff = new StringBuffer();
  while ((line=br.readLine())!=null){
     if (buff.length() > 0){
        buff.append("\n");
     }
     buff.append(line);
  }
  br.close();
  return buff.toString();
}

}

【讨论】:

  • 我现在为脚本使用一个临时文件。但我会试试你的代码......因为我不喜欢临时文件。谢谢。
  • 它不起作用。脚本应输出“OK”字符串。我不明白 -> 脚本没有正确启动...怎么了?
  • 您是否支持将“OK”写入 STD 输出?也许脚本将其写入 STDERR?我将此代码与一些 SQL 转换脚本一起使用,它可以正常工作,但如果您愿意,可以向我发送一个不工作脚本的示例,我会检查它。
  • 是的,我敢肯定,因为以下工作(但不是那么理想):将脚本写入临时文件;运行“PERL mytempfile”
猜你喜欢
  • 2010-09-26
  • 2012-09-29
  • 2013-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-26
  • 2012-09-05
  • 1970-01-01
相关资源
最近更新 更多