Do commands run from current directory in a shell script? - java

In a bash shell script I tried these two versions:
java -jar abc.jar&
and
CMD="java -jar abc.jar&"
$CMD
The first verison works, and the second version complains that abc.jar cannot be found. Why?

Commands do run from current directory in a shell script.
This is why the first command in your test script worked.
The second command may not work because either java isn't in your ${PATH} or abc.jar isn't in your ${CLASSPATH}. You could echo these environment variables or set +x to debug your bash script.

Bash (and others) won't let you do backgrounding (&) within the value of a variable (nor will they let you do redirection that way or pipelines). You should avoid putting commands into variables. See BashFAQ/050 for some additional information.
What is the actual error message you're getting? I bet it's something like "abc.jar& not found" (note the ampersand) because the ampersand is seen as a character in the filename.
Also, the current directory for the script is the directory that it is run from - not the directory in which it resides. You should be explicit about the directory that you want to have your file in.
java -jar /path/to/abc.jar&

Related

Shell script that sets LD_LIBRARY_PATH=`pwd` does not work from Java

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!
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
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.

"No such file or directory" when running java from shell script

I'm trying to run a script from an Amazon Linux machine. The script invokes checkstyle like this (in a script called eval.sh):
CHECKSTYLE="java -jar /home/ec2-user/grader/ext/checkstyle-6.15-all.jar"
CHECKSTYLE_RULES="/home/ec2-user/grader/config/checks.xml"
CHECKSTYLE_OUT="quality.log"
"${CHECKSTYLE}" -c "${CHECKSTYLE_RULES}" -f xml -o "${CHECKSTYLE_OUT}" $(find "${_toCheck}" -name "*.java") 2>"quality.err"
When I run this, I get the following error in quality.err:
./grader/eval.sh: line 10: java -jar /home/ec2-user/grader/ext/checkstyle-6.15-all.jar: No such file or directory
I have tried to run the same command directly in the terminal and it is working. Both checkstyle-6.15-all.jar and checks.xml are where they should be.
What could cause this problem?
Change "${CHECKSTYLE}" to ${CHECKSTYLE} (without the quotes).
You are passing the entire value of the CHECKSTYLE variable as a single word (that's what the quotes do), so the shell is looking for a relative directory named java -jar, and is trying to find a file under that (nonexistent) directory with the path home/ec2-user/grader/ext/checkstyle-6.15-all.jar.
When you envoke "${CHECKSTYLE}" the shell thinks that is the command you are running. There is no such file name with the spaces and options have you have included there. If you envoke it simply as ${CHECKSTYLE} (drop the quotes) the shell will process it for whitespace as normal and split it into the appropriate pieces for creating the process.

Launch Java with a specific argument each time

I have a program which allows me to define the java executable (/usr/bin/java), but does not allow me to add specific arguments to the executable.
I want to be able to run Java with a specific argument each time in order to enable Security Manager.
So far, I have tried to add the argument after /usr/bin/java, so it looks like
java=/usr/bin/java -Djava.security.manager -Djava.security.policy=/home/java.policy
That did not work as the program probably checks to see if a file exists. Another way I tried was to make a bash script called java which contained:
/usr/bin/java -Djava.security.manager -Djava.security.policy=/home/java.policy $*
I then set the java path to /home/java (Location of my script). That however did not work either. Is there some sort of way I can do this?
Thanks.
Put your java call in a shell script java.sh:
#!/bin/bash
/usr/bin/java -Djava.security.manager -Djava.security.policy=/home/java.policy $#
Change permissions with chmod u+x java.sh, then call your program with java=./java.sh (adapt path for your script as needed).
Notes about executable bit and shebang line
Both the shebang line (#!/bin/bash) and execute permission are important here. Without them, system calls of the exec* family will fail because the kernel does not know what to do with the file or because execution is rejected due to the missing executable bit.
This is different when run directly from a shell (./java.sh), because most shells have some compatibility feature for that case so they will run a script in a shell if exec* fails. The execute permission must be set though.
The only case where neither is needed is if you give your script as argument to the shell: bash java.sh.
Your second approach would be ok, but your problem is likely to be that your Multicraft application is not finding your script. More so, it's the environment of your web server (Apache?) that may need to have PATH altered to be able to find your java wrapper script.

OSX How do I have a Shell script change directory to the one the script is in?

I'm using Apple's automator to create a Shell Script. I can get it to run if I change directory specifically to where the jar file is. But what if I want to change to directory to wherever the Shell script happens to be running?
Right now I have the following, which works:
cd desktop/CommonDenom/
java -XstartOnFirstThread -jar CommonDenom.jar
I know there's a way to target whatever directory the Shell script is launched from, but I can't seem to get anything to work. Please be specific with instructions as I havent been using Automator very long. Unless someone can specify how ot writ ethe script without Automator. Thanks in advance.
A standard idiom for this in shell scripts is dirname $0. The $0 variable is the path to the script that was executed, and the dirname command takes a path and strips off the last component to leave the path to the containing directory
cd "`dirname $0`"
Just wanted to weigh in here. I've seen some people with this problem. If you are JUST on OSX and making your own scripts. This will do the trick :) kind of a hack, but works like a charm.
#! /bin/bash
sudo /Applications/XAMPP/xamppfiles/xampp startapache
open /Applications/XAMPP/htdocs
#!/bin/bash
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
cd "${DIR}"
...the rest of your script...
Credits to Ian C. on AskDifferent: https://apple.stackexchange.com/a/179064
I am not sure you mean "you want to change directory to wherever the script is run from" because you will be in the directory the script is run from when you start anyway, so there will be no need to change directory there. I think you mean you want the script to stay wherever it starts, yet still be able to find the jar file.
In which case, you probably jus need the following without any changing directory:
java -XstartOnFirstThread -jar ~/Desktop/CommonDemon/CommonDemon.jar

Shell script: How to put absolute path into command?

I was trying to execute my java program through shell script so I wrote:
java -jar $(pwd)"/test.jar"
It worked flawlessly but when I turned to the code below:
PATH=$(pwd)"/test.jar"'
java -jar $PATH
Then I got an error: "Run.sh: 3: java: not found"
(Running on Ubuntu)
I have very little experience in shell script so please let me know what's wrong with it. Thanks.
PATH is a special environment variable which the shell uses to find executables. You've changed PATH to point at test.jar, so now the shell can't find java.
Call your variable something else.
Example:
LIB_PATH="$(pwd)/test.jar"
java -jar ${LIB_PATH}
The value in $(PWD) depends on the directory the script is called from (print working directory). If you call the script from another directory, than the one your jar-files resides in, you'll get the wrong path. And you changed the search path of the SHELL, that will prevent the shell from finding any other binary e.g. java.
PATH is system-reserved variable, that define the way where your system should look to find the executable (in your case java). Therefore you shouldn't use it in your code as variable to your test.jar .
In my opinion, your code should be something like:
#!/bin/sh
PROGPATH='/path/to/your/test.jar'
JAVAEXEC=`which java`
JAVAPARAMS='-j'
GLOBALPATH="$JAVAEXEC $JAVAPARAMS $PROGPATH"
echo $GLOBALPATH

Categories