0

shell script file directory: /some/location/myShellScript.sh

Properties-Type: shell script (application/x-shellscript)

EDIT

content of shell script:

#!/bin/bash
export LD_LIBRARY_PATH=`pwd`
echo `pwd`
./someExecutable ../input/cfg/test1.ini

The test1.ini is generated one step before in the java code, it provides settings for some testing, which is done in the background. Then the shell script ends up with the file I need for further processing.

/EDIT

When I am running this shell script on linux terminal in its own directory just with "./myShellScript.sh" it works perfectly fine...

The part my shell script shall be executed:

//Do something before
//Shell scripts creates a file
String cmd = /some/location/myShellScript.sh;

ProcessBuilder pb = new ProcessBuilder(cmd);

Process process = pb.start();

int exitValue = process.waitFor();

System.out.println(exitValue);

//Afterwards I am processing the generated file

When running my java program as an executable .jar file, this process gets not executed and the exitValue is 127, but I don't know why...

I tried many things like:

  • using the Runtime to exec
  • adding #!/bin/bash or #!/bin/sh on top of the shell script
  • adding a "sh" parameter to the process command in form of String[]

In my execution directory, I changed the permission with chmod 755 -R * recursively so every associated library used by the shell script is indeed available (also due to the fact, that I can just execute it on the terminal).

I really tried to find a proper answer on the internet but I wasn't successful.

And no, I cannot just do everything in java, the shell script is mandatory and cannot be replaced in this case.

Thanks in advance for helpful suggestions!

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
LeRoe93
  • 1
  • 1
  • 3
  • Please [edit the question](https://stackoverflow.com/posts/52098777/edit) and include the content of the shell script, it's difficult to determine why it exits with a non-zero code without seeing what it's doing. – arco444 Aug 30 '18 at 14:05
  • @arco444 - did it. – LeRoe93 Aug 30 '18 at 14:16
  • 1
    You should try using process.directory(new File("/some/location")); to set the directory when the script runs. Otherwise, change the script to use a fully qualified pathname - /some/location/someExecutable – Jamie Aug 30 '18 at 14:46
  • 1
    Dear @Jamie you, Sir, saved my life - thanks! – LeRoe93 Aug 30 '18 at 14:53
  • BTW, much more efficient to use `$PWD` than `$(pwd)`. The latter forks a subshell, runs the `pwd` command in it, writes that command's output to a FIFO, and reads the FIFO back into the parent shell; the former just evaluates directly to the current working directory with none of that mess/overhead. – Charles Duffy Aug 30 '18 at 15:45
  • Still wondering: Is the current directory the good one when executed via JAVA? – Jay jargot Aug 31 '18 at 14:58

2 Answers2

1

The 127 exit status means that a command used in the script is not found.

EDIT

Debug the script, when bash is used, add the line below on the second line:

exec > /tmp/debug.txt 2>&1 ; set -x

After the next attempt, analyze the traces generated into the /tmp/debug.txt file.

OLD INTRO (the script content was not yet provided) The Java program which executes the myShellScript.sh script has probably not the same PATH environment variable than the one which is set in your environment when you execute the script manually from a terminal.

Jay jargot
  • 2,745
  • 1
  • 11
  • 14
  • You can get the inputstreams of the stdout and stderr of your script in Java from the Process (getInputStream(), getErrorStream()) too. You can log them using your logger in your java code (that may be useful later too, and you neither have to maintain the script's logs, nor have to check you appserver's logs, everything will be on the same place). – m4gic Aug 30 '18 at 14:05
  • The script presented will not attempt to locate the executable in the `PATH`, because the command name (`./someExecutable`) contains a `/` character. – John Bollinger Aug 30 '18 at 15:49
  • @JohnBollinger : ha ok, the question had been edited and I can see the script content now, and yes you are right. Adding the debug line will help anyway I believe: is the current directory the good one? .... – Jay jargot Aug 31 '18 at 14:51
1

The script you are executing is highly sensitive to its working directory. It uses pwd to set the LD_LIBRARY_PATH and it attempts to execute another program via a relative path to that program, providing a relative path as a command-line argument, as well.

The working directory for an execution of the script has no essential relationship with the directory in which the script resides -- it completely depends on how and in what context the script is launched. For example, you report that the script works as you expect "When I am running this shell script [...] in its own directory." But when you run the script from Java you very likely are not running it with its own directory as the working directory, and that will strongly affect this script's behavior.

One solution would be to hardcode the script's installation path into the script itself, and to express all your paths relative to that:

#!/bin/bash

installation_dir=/path/to/the/script/dir

export LD_LIBRARY_PATH=$installation_dir
"$installation_dir"/someExecutable "$installation_dir"/../input/cfg/test1.ini

It's a bit kludgy to hardcode the path, though. You could further improve it by having the script identify its own directory at runtime:

#!/bin/bash

installation_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"

export LD_LIBRARY_PATH=$installation_dir
"$installation_dir"/someExecutable "$installation_dir"/../input/cfg/test1.ini

That's obviously Bash-specific, but you were using bash anyway. Alternatively, if the executable your script launches is also sensitive to its working directory, then perhaps you just want the script to change directory (which will be effective only for the script and processes downstream from it, not for its parent process):

#!/bin/bash

cd "$( dirname "${BASH_SOURCE[0]}" )"

export LD_LIBRARY_PATH=`pwd`
./someExecutable ../input/cfg/test1.ini
John Bollinger
  • 160,171
  • 8
  • 81
  • 157