我有一个java代码,它接受数据文件,将数据复制到perl脚本,并从shell脚本调用perl脚本。以下是相关代码:
public String returnStringForPerlScript(ArrayList<String> arrayContainingPerlScriptArguments, String singularFilePath) throws IOException{
String argFileName = null;//5
String argParsedFileName = null;//
argParsedFileName = arrayContainingPerlScriptArguments.get(4);
argFileName = arrayContainingPerlScriptArguments.get(5);
System.out.print("ARG1: "+argFileName);
System.out.print(" ARG2: "+argParsedFileName);
String runCmdString = singularFilePath+"perlscript.pl";
String runCmd = singularFilePath+"runPerlScript.sh";
return runCmd;
}
上面的代码是一个单独的类中的方法。下面的代码是实际初始化和运行Process的地方。
p = dfp.returnStringForPerlScript(perlParam, singularDirectoryPath);
System.out.println("Running from: "+p);
process = Runtime.getRuntime().exec(p);
令人困惑的是,这段代码在早期工作得非常好,我改变的只是输出目录。我写了一个完全不同的文件路径,而不是“singularDirectoryPath”。我很困惑,因为我不知道代码有什么问题,考虑到以前运行过。当我从终端调用“runPerlScript.sh”时,它起作用了。
我还应该补充说我确实尝试使用String []而不是字符串,如下所示:
String[] cmdArray = {"/bin/tcsh","-c","/filepath/runPerlScript.sh"};
Process p = Runtime.getRuntime().exec(cmdArray);
仍然没有生成任何输出文件。
答案 0 :(得分:1)
验证两件事:
如果您修改了perl脚本,请确保第一行中有#!/bin/perl
,shell脚本相同,如果您有#!/bin/sh
或#!/bin/bash
特别是使用bash。
您移动的文件必须具有可执行权限,请使用类似的内容进行更改。chmod 755 myFile
。
答案 1 :(得分:1)
您陈述问题的方式似乎无法解决。因为这曾经显然改变了两件事之一:无论是你的java执行环境还是你的OS环境(这就是为什么首先想到文件权限的原因)。
由于您可以手动执行脚本,因此最可能的原因似乎是java由于某种原因无法执行脚本。
请将以下代码添加到您的java程序中,并检查操作系统返回的退出代码。
System.out.println("Waiting for process to finish...");
process.waitFor(); // wait until the process finishes
int exitCode = process.exitValue();
System.out.println("Process exit code: " + exitCode);
编辑:在评论中提供的说明之后,最可能的情况是Java正在错误地传递脚本的命令行参数。测试它相对容易:只需将第一行作为第一行添加到shell脚本命令echo $1 $2 $3
中,以获取尽可能多的参数。这样,您将确定是否正确传递参数。如果没有,那么问题出在Java方面,我们应该使用exec()
的String []版本。我习惯Processbuilder
所以我会在我的例子中使用它(请在执行上述测试后使用下面的代码,以便我们知道缺少哪些参数):
String shellScript = "/some/path/runPerlScript.sh";
String perlScript = "/some/path/perlscript.pl";
// similar to using exec() version with String[]
ProcessBuilder pb = new ProcessBuilder(shellScript , perlScript);
// print what the process will see as current directory
File workDir = pb.directory();
System.out.println("Working directoy:" + workDir.getAbsolutePath());
// print the environment variables visible to the process
Map<String, String> env = pb.environment();
System.out.println("Environment available to shell script:\n" + env);
// set the working directory if needed depending on the output of the workDir above
pb.directory(new File("/some/path"));
Process p = pb.start();
// add the lines from the previous snipet here that waits until the process is done
答案 2 :(得分:0)
我看了一些Javadocs并为我的问题提出了这个解决方案。不知道它为什么会起作用,但它确实有效!
ProcessBuilder builder = new ProcessBuilder(p1);
builder.directory(dirFile);
Process process = builder.start();
System.out.println("Process working directory: "+builder.directory().getAbsolutePath());
InputStream is = process.getInputStream();
InputStreamReader reader = new InputStreamReader(is);
Scanner scan = new Scanner(reader);
while(scan.hasNextLine()){
System.out.println(scan.nextLine());
}
基本上,我只是指定了ProcessBuilder的工作目录。我还将一个String []传递给了ProcessBuilder而不是一个字符串,我在我的字符串数组中指定了我的shell。