Below is a combination of Patrick's solution, Maarteen Boekhold's solution, and foozbar's comment that works with both Linux and Cygwin:
#!/bin/bash
// 2>/dev/null; SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )"
// 2>/dev/null; OPTS="-cp $SCRIPT_DIR/lib/extra.jar:$SCRIPT_DIR/lib/spring.jar"
// 2>/dev/null; OPTS="$OPTS -d"
// 2>/dev/null; OPTS="$OPTS -Dlog4j.configuration=file:/etc/myapp/log4j.xml"
// 2>/dev/null; exec groovy $OPTS "$0" "$@"; exit $?
import org.springframework.class.from.jar
//other groovy code
println 'Hello'
How it works:
//
is a valid groovy comment, so all of the bash commands are ignored by Groovy.
//
will return an error, but the error output is redirected to /dev/null
and is therefore not displayed.
- bash executes commands following a semicolon even though the previous command failed.
exec
replaces the current program in the current process without forking a new process. Thus, groovy runs within the original script process (ps
shows the process as the script rather than the groovy executable)
- The
exit $?
statement following exec groovy
prevents bash from trying to interpret the rest of the script as a bash script, and also preserves the return code from the groovy script.
The above bash trick is more convenient in some cases than the RootLoader trick because you can use regular import statements within the script. Using the RootLoader trick forces you to load all of the classes using reflection. This is fine in some situations (such as when you need to load a JDBC driver), but inconvenient in others.
If you know your script will never be executed on Cygwin, then using Patrick's or Maarteen's solution will likely result in slightly better performance because they avoid the overhead of generating and throwing away an error.