在bash中没有从此java命令重定向标准错误

时间:2010-09-30 12:30:18

标签: java linux bash unix shell

我有以下shell脚本。由于某种原因,java程序的标准错误和标准输出不会打印到文件“log”,而是始终显示在控制台中。是否存在某种类型或者我遗漏了什么?

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&

3 个答案:

答案 0 :(得分:3)

令人遗憾的是,如果要将重定向运算符保留在字符串值中,则必须使用eval

与其他shell特殊字符一样,仅在未引用重定向运算符时对其进行评估。展开JAVACMD参数时,它将在空白上拆分,但不会重新评估它包含的任何特殊字符。使用eval强制进行此重新评估。

eval的问题是强制重新评估每个字符。在您的情况下,其他任何角色都不会有任何不良影响。如果您的字符串值包含一些其他shell特殊字符(例如;(){} ...),您不希望shell重新评估,则必须转义/引用它 in 字符串值所以eval不会给它一个特殊的含义。

⋮
eval "$JAVACMD &"

为避免eval出现问题,我建议将重定向移出字符串值:

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

通过这种方式,您需要注意的字符串值中唯一的字符是空白字符(例如,如果您在其中一个选项/参数中需要一些嵌入的空格;如果您遇到此问题,您可能会考虑使用数组变量或"$@"(所有类似Bourne的shell中可用的单数,类似数组的变量))。

答案 1 :(得分:2)

你试过了吗?

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 &

重定向被视为java命令的参数,因为它们包含在变量中。

答案 2 :(得分:1)

你实际上不能将重定向粘贴在这样的变量中,并期望bash接受它们。简单的例子:

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

即。你的重定向指标正在变成简单的参数,传递给你的java调用。

一种解决方法是说eval $JAVACMD,但它不会让你的脚本更清洁。