Java调用lowercase.perl脚本异常:<lower.eng>参数无法正常工作
解决Java调用Perl脚本时输入重定向失效的问题
我帮你捋清楚问题出在哪:当你在终端直接跑perl lowercase.perl < lower.eng时,< lower.eng是shell负责处理的输入重定向,它会把lower.eng的内容作为Perl脚本的标准输入。但Java的Runtime.exec()或者ProcessBuilder默认是直接启动Perl进程,不会通过shell解析命令,所以< lower.eng会被当成普通的命令行参数传给你的Perl脚本,而不是实现输入重定向——这就是为什么脚本能执行,但参数没生效的原因。
下面给你两种可行的解决方案:
方案1:通过shell执行整个命令
既然重定向是shell的功能,那我们可以让Java启动一个shell进程,让shell帮我们处理重定向逻辑。
Linux/macOS系统
用bash -c来包裹完整的命令:
import java.io.IOException; public class CallPerlScript { public static void main(String[] args) { try { // 完整命令交给bash处理,包括重定向 ProcessBuilder pb = new ProcessBuilder("bash", "-c", "perl lowercase.perl < lower.eng > output.txt"); // 确保工作目录是脚本和文件所在的目录 pb.directory(new java.io.File(System.getProperty("user.dir"))); Process process = pb.start(); // 等待脚本执行完成,并获取退出码 int exitCode = process.waitFor(); System.out.println("脚本执行完成,退出码:" + exitCode); } catch (IOException | InterruptedException e) { e.printStackTrace(); } } }
Windows系统
换成cmd /c:
import java.io.IOException; public class CallPerlScript { public static void main(String[] args) { try { ProcessBuilder pb = new ProcessBuilder("cmd", "/c", "perl lowercase.perl < lower.eng > output.txt"); pb.directory(new java.io.File(System.getProperty("user.dir"))); Process process = pb.start(); int exitCode = process.waitFor(); System.out.println("脚本执行完成,退出码:" + exitCode); } catch (IOException | InterruptedException e) { e.printStackTrace(); } } }
方案2:Java手动处理输入输出(跨平台推荐)
这种方式不需要依赖shell,Java自己负责读取输入文件,把内容传给Perl进程,再把Perl的输出写入目标文件,兼容性更好。
import java.io.*; public class CallPerlScript { public static void main(String[] args) { try { // 启动Perl脚本进程,不需要传重定向参数 ProcessBuilder pb = new ProcessBuilder("perl", "lowercase.perl"); pb.directory(new java.io.File(System.getProperty("user.dir"))); Process process = pb.start(); // 1. 读取lower.eng的内容,写入Perl进程的标准输入 try (BufferedReader inputFileReader = new BufferedReader(new FileReader("lower.eng")); OutputStream processInput = process.getOutputStream()) { String line; while ((line = inputFileReader.readLine()) != null) { processInput.write((line + System.lineSeparator()).getBytes()); } // 关闭输入流,告诉Perl脚本没有更多输入了 processInput.flush(); processInput.close(); } // 2. 读取Perl进程的标准输出,写入output.txt try (BufferedReader processOutput = new BufferedReader(new InputStreamReader(process.getInputStream())); BufferedWriter outputFileWriter = new BufferedWriter(new FileWriter("output.txt"))) { String line; while ((line = processOutput.readLine()) != null) { outputFileWriter.write(line); outputFileWriter.newLine(); } } // 等待脚本执行完成 int exitCode = process.waitFor(); System.out.println("脚本执行完成,退出码:" + exitCode); } catch (IOException | InterruptedException e) { e.printStackTrace(); } } }
额外注意事项
- 确保你的Java程序的工作目录确实是脚本和文件所在的目录,如果不确定,可以用绝对路径替换文件名(比如
/home/you/yourdir/lower.eng)。 - Linux/macOS下如果直接执行
./lowercase.perl,要先给脚本加执行权限:chmod +x lowercase.perl,否则还是用perl lowercase.perl的方式调用更稳妥。 - 可以打印Perl脚本的错误输出(
process.getErrorStream())来排查问题,比如脚本有没有报错。
内容的提问来源于stack exchange,提问作者user9238004
相关产品推荐
相关产品推荐

