1

我有一个 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);

仍然没有生成任何输出文件。

4

3 回答 3

1

你陈述问题的方式似乎无法解决。由于这曾经显然可以工作,因此发生了两件事之一:您的 java 执行环境或您的操作系统环境(这就是为什么首先想到文件权限的原因)。

由于您可以手动执行脚本,因此最可能的原因似乎是 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 端,我们应该使用 String[] 版本的exec(). 我已经习惯了,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
于 2013-07-25T21:49:17.913 回答
1

验证两件事:

  • 如果您修改了 perl 脚本,请确保它#!/bin/perl在第一行中,对于您的 shell 脚本,它必须有,#!/bin/sh或者#!/bin/bash如果您特别使用 bash。

  • 您移动的文件必须具有可执行权限,使用类似 . chmod 755 myFile.

于 2013-07-25T21:16:31.820 回答
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。

于 2013-07-26T17:22:16.477 回答