views:

57

answers:

3

I have the following shell script. For some reason the java program's standard error and standard output is not printed to the file "log" but instead always appear in the console. Is there a type some where or am I missing something?

JAVACMD="java -XX:+HeapDumpOnOutOfMemoryError -Dcom.sun.management.jmxremote  -Dcom.sun.management.jmxremote.port=19000 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Xss128k -Xmx700m -jar program.jar >log 2>&1 "

echo "Starting server...";
$JAVACMD&
+1  A: 

You can't actually stick redirections in a variable like that and expect bash to accept them. Simple example:

tesla:~ peter$ ECHOCMD='echo > log 2>&1'
tesla:~ peter$ $ECHOCMD
log 2>&1

I.e. your redirection indicators are becoming simple arguments, passed to your java invocation.

One workaround is to say eval $JAVACMD but it won't make your script any cleaner.

Habbie
+2  A: 

Have you tried:

JAVACMD="java -XX:+HeapDumpOnOutOfMemoryError -Dcom.sun.management.jmxremote  -Dcom.sun.management.jmxremote.port=19000 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Xss128k -Xmx700m -jar program.jar"

echo "Starting server...";
$JAVACMD >log 2>&1 &

The redirections are considered as arguments to the java command as they are contained in the variable.

Didier Trosset
+3  A: 

Regrettably, you will have to use eval if you want to keep the redirection operators in the string value.

Like other shell-special characters, redirection operators are only evaluated if they are not quoted. When you expand the JAVACMD parameter it will split on whitespace, but it will not re-evaluate any special characters it includes. Using eval forces this re-evaluation.

The problem with eval is it forces every character be re-evaluated. In your case, none of the other characters will have any untoward affects. If your string value contained some other shell-special character (e.g. ;(){}…) that you did not want the shell to re-evaluate you would have to escape/quote it inside the string value so that eval would not give it a special meaning.

⋮
eval "$JAVACMD &"

To avoid problems with eval, I suggest moving the redirection out of the string value:

JAVACMD="… program.jar"
⋮
$JAVACMD >log 2>&1 &

Done this way the only characters in the string value that you need to watch out for are the whitespace characters (e.g. if you needed some embedded whitespace in one of the options/arguments; if you run into this you might consider using an array variable or "$@" (a singular, array-like variable available in all Bourne-like shells)).

Chris Johnsen