在bash中无法从此java命令重定向的标准错误
我有下面的shell脚本。由于某些原因,java程序的标准错误和标准输出不会打印到文件“log”中,而是始终显示在控制台中。是否有某种类型,或者我遗漏了什么在bash中无法从此java命令重定向的标准错误,java,linux,bash,unix,shell,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.
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&
实际上,您不能将重定向粘贴到这样的变量中,并期望bash接受它们。简单的例子:
tesla:~ peter$ ECHOCMD='echo > log 2>&1'
tesla:~ peter$ $ECHOCMD
log 2>&1
也就是说,重定向指示符正在变成简单的参数,传递给java调用
一种解决方法是说
eval$JAVACMD
,但这不会使脚本更干净。您不能在这样的变量中插入重定向,并期望bash接受它们。简单的例子:
tesla:~ peter$ ECHOCMD='echo > log 2>&1'
tesla:~ peter$ $ECHOCMD
log 2>&1
也就是说,重定向指示符正在变成简单的参数,传递给java调用
一种解决方法是说eval$JAVACMD
,但它不会使您的脚本更干净。您是否尝试过:
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命令的参数,因为它们包含在变量中。您是否尝试过:
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命令的参数,因为它们包含在变量中。遗憾的是,如果要将重定向运算符保留在字符串值中,则必须使用
eval
与其他shell特殊字符一样,重定向运算符只有在未被引用时才被计算。当您展开JAVACMD参数时,它将在空白处拆分,但不会重新计算它包含的任何特殊字符。使用eval
强制重新评估
eval
的问题是它强制重新计算每个字符。在您的情况下,其他角色都不会有任何不良影响。如果字符串值包含不希望shell重新计算的其他shell特殊字符(例如,;(){}
…),则必须在字符串值中转义/引用它,以便eval
不会赋予它特殊含义
⋮
eval "$JAVACMD &"
为了避免
eval
出现问题,我建议将重定向移出字符串值:
JAVACMD="… program.jar"
⋮
$JAVACMD >log 2>&1 &
这样做,字符串值中唯一需要注意的字符是空白字符(例如,如果您需要在一个选项/参数中有一些嵌入的空白),如果碰到这个,您可能会考虑使用数组变量或<代码>“$@”/COD>(一个奇异的、数组式的变量,可在所有的Burne样shell中使用)。).
很遗憾,如果要将重定向运算符保留在字符串值中,则必须使用eval
与其他shell特殊字符一样,重定向运算符只有在未被引用时才被计算。当您展开JAVACMD参数时,它将在空白处拆分,但不会重新计算它包含的任何特殊字符。使用eval
强制重新评估
eval
的问题是它强制重新计算每个字符。在您的情况下,其他角色都不会有任何不良影响。如果字符串值包含不希望shell重新计算的其他shell特殊字符(例如,;(){}
…),则必须在字符串值中转义/引用它,以便eval
不会赋予它特殊含义
⋮
eval "$JAVACMD &"
为了避免
eval
出现问题,我建议将重定向移出字符串值:
JAVACMD="… program.jar"
⋮
$JAVACMD >log 2>&1 &
这样做,字符串值中唯一需要注意的字符是空白字符(例如,如果您需要在一个选项/参数中有一些嵌入的空白),如果碰到这个,您可能会考虑使用数组变量或<代码>“$@”/COD>(一个奇异的、数组式的变量,可在所有的Burne样shell中使用)。).
另请参见。另请参见。