简体   繁体   中英

Java not running shell script

I have a java code that takes a data file, copies the data to a perl script, and calls the perl script from a shell script. Here is the relevant code:

    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;
}

The code above is a method in a separate class. The code below is where the Process is actually initialized and ran.

p = dfp.returnStringForPerlScript(perlParam, singularDirectoryPath);
System.out.println("Running from: "+p);
process = Runtime.getRuntime().exec(p);

What is confusing is that this code worked perfectly well earlier, and all I changed is the output directory. Instead of "singularDirectoryPath", I had written out a completely different file path. I am very confused because I have no idea what is wrong with the code, considering it ran before. When I called "runPerlScript.sh" from the terminal, it worked.

I also should add that I did try to use a String[] instead of a string, as shown below:

    String[] cmdArray = {"/bin/tcsh","-c","/filepath/runPerlScript.sh"};
    Process p = Runtime.getRuntime().exec(cmdArray);

Still did not generate any output files.

Verify two things:

  • If you have modified the perl script, make sure it has #!/bin/perl in the first line, same for your shell script, it must have #!/bin/sh or #!/bin/bash if you are specificaly using bash.

  • Your moved files must have executable permissions, change them with something like . chmod 755 myFile .

The way you state the problem seems unsolvable. Since this used to work apparently one of two things changed: Either your java execution environment or your OS environment (this is why file permissions come to mind first).

Since you can execute the scripts manually the most probable cause seems to be that java cannot execute the scripts for some reason.

Please add the code below to your java program and check what is the exit code returned by the OS.

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); 

Edit: After the clarifications provided in the comments the most probable scenario is that command line arguments to your script are being passed incorrectly by Java. It is relatively easy to test that: Just add as a first line to your shell script command echo $1 $2 $3 for as many arguments as it takes. This way you will identify if arguments are being passed correctly. If not, then the problem lies on Java side and we should use the String[] version of exec() . I am used to Processbuilder so I will use that in my example (please use the code below after you have performed the test above so we know what arguments are missing):

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

I took a look at some Javadocs and came up with this solution for my problem. Don't know exactly why it works, but it works!

    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());
        }

Basically, I just specified the working directory of the ProcessBuilder. I also passed a String[] to ProcessBuilder instead of a string, and I specified my shell in my string array.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM