【问题标题】:Standard error not getting redirected from this java command in bash标准错误未从 bash 中的此 java 命令重定向
【发布时间】:2010-09-30 12:30:17
【问题描述】:

我有以下 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&

【问题讨论】:

标签: java linux bash unix shell


【解决方案1】:

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

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

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

⋮
eval "$JAVACMD &"

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

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

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

【讨论】:

    【解决方案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 命令的参数,因为它们包含在变量中。

    【讨论】:

      【解决方案3】:

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

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

      即您的重定向指示符正在成为简单的参数,传递给您的 java 调用。

      一种解决方法是说eval $JAVACMD,但它不会使您的脚本更清晰。

      【讨论】:

        猜你喜欢
        • 2015-06-02
        • 1970-01-01
        • 1970-01-01
        • 2010-10-12
        • 2021-06-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多