I'm a new for Mac developing.
I try to create project.sh file and run it via Terminal
See mac.zip for more details.
The main class (com.myclass.MyClass) is in "main.jar" that requires lib1.jar, lib2.jar, and sublib1.jar
The "CLASSPATH" property in "project.sh" is created via script, it cannot be changed in project.sh
The value is always in relative path format such as "../../lib/lib1.jar"
When I try to run it from "mac/project" directory that contains main.jar and project.sh via Mac Terminal
It work fine as following
Gui-iMac:project gui$ ./project.sh
AClass
BClass
CClass
However, when I try to run project.sh from other directory, it failed.
For example: run from desktop directory:
Gui-iMac:desktop gui$ "/Users/gui/Desktop/GUI/Mac/project/project.sh"
Error: Could not find or load main class com.myclass.MyClass
How can I run project.sh from other directory?
Please help me to solve this problem.
Thanks in advance.
earist
I don't know if this is the answer that you are looking for but to run a .sh script from another directory you can use
$sh /Users/gui/Desktop/GUI/Mac/project/project.sh
Now, I find the solution for this problem.
using
cd "$directoryName" && exec "$myCommand"
as following:
#!/bin/bash
BASE=$(dirname "$0")
ARGS=""
if [ $# -gt 1 ]; then
while [ $# -ge 1 ]; do
case "$1" in
-[a-z]*) ARGS="$ARGS $1" ;;
*) ARGS="$ARGS \"$1\"" ;;
esac
shift
done
fi
CLASSPATH=.:../lib/lib1.jar:../lib/lib2.jar:./lib/sublib1.jar:./main.jar
JAVA_COMMAND=java
VM_OPTIONS="-Xmx800M"
EXEC_COMMAND="cd \"$BASE\" && exec $JAVA_COMMAND $VM_OPTIONS -cp $CLASSPATH com.myclass.MyClass $ARGS"
eval $EXEC_COMMAND
Related
I am new to bash. I am trying to configure searchguard(a plugin of elasticsearch). For this, I need to run the sgadmin.sh file. Below is the content of the file.
#!/bin/bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
BIN_PATH="java"
if [ -z "$JAVA_HOME" ]; then
echo "WARNING: JAVA_HOME not set, will use $(which $BIN_PATH)"
else
BIN_PATH="$JAVA_HOME/bin/java"
fi
"$BIN_PATH" $JAVA_OPTS -Dorg.apache.logging.log4j.simplelog.StatusLogger.level=OFF -cp "$DIR/../*:$DIR/../../../lib/*:$DIR/../deps/*" com.floragunn.searchguard.tools.SearchGuardAdmin "$#"
Below is the error received when we run the sgadmin.sh file.
$(BASH_SOURCE[0]): bad substitution
Error: Could not find or load main class com.floragunn.searchguard.tools.SearchGuardAdmin
Can anyone explain what does the above code means, more specifically the last line
"$BIN_PATH" $JAVA_OPTS -Dorg.apache.logging.log4j.simplelog.StatusLogger.level=OFF -cp "$DIR/../*:$DIR/../../../lib/*:$DIR/../deps/*" com.floragunn.searchguard.tools.SearchGuardAdmin "$#"
Note:
Our environment is Windows server 2012
To execute the .sh file, we have copied the SH folder to C:\ drive and added this to environment variables(path).
I have a bash script that does except some actions the following:
mv "$currentDir" "$currentDir#backup"
mv "$tempBuild" "$currentDir"
I run my script by doing two steps:
cd /path/to/project
./my_script.sh
I expected that $currentDir should always be equated to /path/to/project.
But when I run it second time by adding the 3rd step ./my_script.sh the current directory value becomes /path/to/project#backup.
What am I doing wrong, is it possible to improve the script for doing that stuff or should I change an approach?
Also I'm getting the current directory by this way:
currentScriptAbsolutePath=$(cd `dirname "${BASH_SOURCE[0]}"` && pwd)/`basename "${BASH_SOURCE[0]}"`
currentDirAbsolutePath=$(dirname $currentScriptAbsolutePath)
Any help is appreciated and thank you in advance.
In my toolbox I have this to get the script path and the caller path.
This can help you
# Set path
CALLER_PWD=$(pwd)
case "$0" in
*/*)
SCRIPT_PWD=`dirname "$0"`
;;
*)
SCRIPT_PWD=`/bin/which "$0" | head -1`
SCRIPT_PWD=`dirname "$SCRIPT_PWD"`
;;
esac
cd "$SCRIPT_PWD"
SCRIPT_PWD=$(pwd)
cd "$CALLER_PWD"
I'm not a pro in shell scripting, thats why I ask here :).
Let's say I got a folder. I need a script that monitors that folder for new files (no prefix name of files is given). When a new file gets copied into that folder, another script should start. Has the second script processed the file successfully the file should be deleted.
I hope you can give me some ideas on how to achieve such script :)
Thank you very much in advance.
Thomas
Try this:
watcher.sh:
#!/bin/bash
if [ -z $1 ];
then
echo "You need to specify a dir as argument."
echo "Usage:"
echo "$0 <dir>"
exit 1
fi
while true;
do
for a in $(ls -1 $1/* 2>/dev/null);
do
otherscript $a && rm $a #calls otherscript with the file a as argument and removes it if otherscript returned something non-zero
done
sleep 2s
done
Don't forget to make it executable
chmod +x ./watcher.sh
call it with:
./watcher.sh <dirname>
try inotify(http://man7.org/linux/man-pages/man7/inotify.7.html)
or you may need to install inotify-tools (http://www.ibm.com/developerworks/linux/library/l-ubuntu-inotify/) to use it by shell.
Ok so I have written a .sh file in Linux Ubuntu and it works perfectly. However on a Mac it always returns that the file was not found even when it is in the same directory. Can anyone help me out?
.sh file:
if [ ! -f file-3*.jar ]; then
echo "[INFO] jar could not be found."
exit
fi
Just thought I'd add, this isn't for more than one file, it's for a file that is renamed to multiple endings.
In a comment to #Paul R's answer, you said "The shell script is also in the same directory as the jar file. So they can just double click it after assigning SH files to open with terminal by default." I suspect that's the problem -- when you run a shell script by double-clicking it, it runs with the working directory set to the user's home directory, not the directory where the script's located. You can work around this by having the script cd to the directory it's in:
cd "$(dirname "$BASH_SOURCE")"
EDIT: $BASH_SOURCE is, of course, a bash extension not available in other shells. If your script can't count on running in bash, use this instead:
case "$0" in
*/*)
cd "$(dirname "$0")" ;;
*)
me="$(which "$0")"
if [ -n "$me" ]; then
cd "$(dirname "$me")"
else
echo "Can't locate script directory" >&2
exit 1
fi ;;
esac
BTW, the construct [ ! -f file-3*.jar ] makes me nervous, since it'll fail bizarrely if there's ever more than one matching file. (I know, that's not supposed to happen; but things that aren't supposed to happen have any annoying tendency to happen anyway.) I'd use this instead:
matchfiles=(file-3*.jar)
if [ ! -f "${matchfiles[0]}" ]; then
...
Again, if you can't count on bash extensions, here's an alternative that should work in any POSIX shell:
if [ ! -f "$(echo file-3*.jar)" ]; then
Note that this will fail (i.e. act as though the file didn't exist) if there's more than one match.
I think the problem lies elsewhere, as the script works as expected on Mac OS X here:
$ if [ ! -f file-3*.jar ]; then echo "[INFO] jar could not be found."; fi
[INFO] jar could not be found.
$ touch file-302.jar
$ if [ ! -f file-3*.jar ]; then echo "[INFO] jar could not be found."; fi
$
Perhaps your script is being run under the wrong shell, or in the wrong working directory ?
It's not that it doesn't work for you, it doesn't work for your users? The default shell for OS X has changed over the years (see this post) - but it looks like your comment says you have the #! in place.
Are you sure that your users have the JAR file in the right place? Perhaps it's not the script being wrong as much as it's telling you the correct answer - the required file is missing from where the script is being run.
This isn't so much an answer, as a strategy: consider some serious logging. Echo messages such as "[INFO] jar could not be found." both to the screen and to a log file, then add extra logging, such as the values of $PWD, $SHELL and $0 to the log. Then, when your customers/co-workers try to run the script and fail, they can email the log to you.
I would probably use something like
screenlog() {
echo "$*"
echo "$*" >> $LOGFILE
}
log() {
echo "$*" >> $LOGFILE
}
Define $LOGFILE at the top of your script. Then pepper your script with statements like screenlog "[INFO] jar could not be found." or log "\$PWD: $PWD".
I am attempting to write a bash script that changes directory and then runs an existing script in the new working directory.
This is what I have so far:
#!/bin/bash
cd /path/to/a/folder
./scriptname
scriptname is an executable file that exists in /path/to/a/folder - and (needless to say), I do have permission to run that script.
However, when I run this mind numbingly simple script (above), I get the response:
scriptname: No such file or directory
What am I missing?! the commands work as expected when entered at the CLI, so I am at a loss to explain the error message. How do I fix this?
Looking at your script makes me think that the script you want to launch a script which is locate in the initial directory. Since you change you directory before executing it won't work.
I suggest the following modified script:
#!/bin/bash
SCRIPT_DIR=$PWD
cd /path/to/a/folder
$SCRIPT_DIR/scriptname
cd /path/to/a/folder
pwd
ls
./scriptname
which'll show you what it thinks it's doing.
I usually have something like this in my useful script directory:
#!/bin/bash
# Provide usage information if not arguments were supplied
if [[ "$#" -le 0 ]]; then
echo "Usage: $0 <executable> [<argument>...]" >&2
exit 1
fi
# Get the executable by removing the last slash and anything before it
X="${1##*/}"
# Get the directory by removing the executable name
D="${1%$X}"
# Check if the directory exists
if [[ -d "$D" ]]; then
# If it does, cd into it
cd "$D"
else
if [[ "$D" ]]; then
# Complain if a directory was specified, but does not exist
echo "Directory '$D' does not exist" >&2
exit 1
fi
fi
# Check if the executable is, well, executable
if [[ -x "$X" ]]; then
# Run the executable in its directory with the supplied arguments
exec ./"$X" "${#:2}"
else
# Complain if the executable is not a valid
echo "Executable '$X' does not exist in '$D'" >&2
exit 1
fi
Usage:
$ cdexec
Usage: /home/archon/bin/cdexec <executable> [<argument>...]
$ cdexec /bin/ls ls
ls
$ cdexec /bin/xxx/ls ls
Directory '/bin/xxx/' does not exist
$ cdexec /ls ls
Executable 'ls' does not exist in '/'
One source of such error messages under those conditions is a broken symlink.
However, you say the script works when run from the command line. I would also check to see whether the directory is a symlink that's doing something other than what you expect.
Does it work if you call it in your script with the full path instead of using cd?
#!/bin/bash
/path/to/a/folder/scriptname
What about when called that way from the command line?