Java没有运行shell脚本

时间:2013-07-25 21:01:54

标签: java

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

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

3 个答案:

答案 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。