eval命令在这个例子中如何工作?与Apache Maven相关

时间:2013-11-06 09:54:41

标签: bash eval

您好我是新手,我无法理解eval命令在这里是如何工作的。 正在评估多少个args? \在这做什么? 谢谢您的帮助!!!

eval "${JAVACMD}" \
 ${MAVEN_OPTS} \
 -classpath "${CLASSWORLDS_JAR}" \
 "-Dclassworlds.conf=${M2_HOME}/bin/m2.conf" \
 "-Dmaven.home=${M2_HOME}"  \
 "-Dos.arch=`uname -m`" \
 ${CLASSWORLDS_LAUNCHER} $(${QUIET_FLAG} && echo \-q) $(${OFFLINE_FLAG} && echo \-o) ${QUOTED_ARGS} ${MAVEN_ARGS}

3 个答案:

答案 0 :(得分:0)

About shell bulletin eval:

  当命令行包含需要由shell评估的内容时,

eval 非常有用。 eval 将一个字符串作为其参数,并将其评估为就像在命令行上键入该字符串一样。

PS:应该谨慎使用它。

\用于行继续在同一命令行的下一行部分生成字符串。

答案 1 :(得分:0)

bash的好手册在这里: http://www.gnu.org/software/bash/manual/bashref.html 这是一份非常好的详细文件。我的答案中的所有引文均来自该手册。

反斜杠'\'是一个逃避角色。它用于新线逃逸。

  

“如果出现\ newline对,并且未引用反斜杠本身,\ newline将被视为续行”

它也在你的例子中用作短跑逃脱:

\-q
\-o

反引号'`'用于命令替换。这意味着对于字符串

uname_m=`uname -m`

'uname_m'变量获取'uname -m'命令的返回值 顺便说一句,命令替换的另一种变体也用在你的代码中:

  

$(...)

它的使用方式与反引号相同。所以以下命令也是如此:

uname_m=`uname -m`
uname_m=$(uname -m)

'eval'用于运行一些外部程序。

  

eval [参数]   参数连接在一起形成一个命令,然后读取并执行该命令,并将其退出状态作为eval的退出状态返回。如果没有参数或只有空参数,则返回状态为零。

我不太明白为什么同一个命令不是按原样放置,不使用'eval',因为它的结果没有被使用(由于你的代码)。

顺便说一下,你可以通过打印所有bash命令的踪迹来查看脚本中发生的事情。 你可以在外部完成,只需运行

bash -x script.sh

或者你可以修改脚本本身。只需加上

set -x

在脚本中进行任何有意义的操作之前。

答案 2 :(得分:0)

看来eval仅用于根据QUIET_FLAGOFFLINE_FLAG的值有条件地向命令行添加一对参数。 (基于代码,它们的值看起来像truefalse,因此执行相同名称的命令)。一个更好的解决方案是将标志设置为任何值以启用它,并保持未设置以禁用它。

"${JAVACMD}" \
  ${MAVEN_OPTS} \
  -classpath "${CLASSWORLDS_JAR}" \
  "-Dclassworlds.conf=${M2_HOME}/bin/m2.conf" \
  "-Dmaven.home=${M2_HOME}"  \
  "-Dos.arch=$(uname -m)" \
  ${CLASSWORLDS_LAUNCHER} ${QUIET_FLAG+:-q} ${OFFLINE_FLAG:+-o} \
  ${QUOTED_ARGS} ${MAVEN_ARGS}

如果将QUIET_FLAG设置为任何非empy值,则其展开将替换为-q;否则,空字符串将被替换,并且它将从命令行中消失,因为它没有被引用。 OFFLINE_FLAG的处理方式类似。这样就不再需要eval

要保留当前的true / false设置,请使用它们设置第二组变量:

# variable names are case-sensitive, so these are separate flags
QUIET_FLAG && quiet_flag=-q
OFFLINE_FLAG && offline_flag=-o

"${JAVACMD}" ... ${CLASSWORLDS_LAUNCHER} $quiet_flag $offline_flag ...

以上内容适用于任何POSIX shell。如果这是bash,则可以通过将选项存储在数组中来简化命令调用本身。这消除了对行继续符的需要,因为可以在多行上指定数组中的值。 shell知道在找到右括号之前数组不完整,而命令行由第一个未转义的换行符终止。

java_opts=( ${MAVEN_OPTS}
            -classpath "${CLASSWORLDS_JAR}"
            "-Dclassworlds.conf=${M2_HOME}/bin/m2.conf"
            "-Dmaven.home=${M2_HOME}" 
            "-Dos.arch=$(uname -m)"
            ${CLASSWORLDS_LAUNCHER}
            ${QUIET_FLAG+:-q}
            ${OFFLINE_FLAG:+-o}
            ${QUOTED_ARGS}
            ${MAVEN_ARGS}
)

"${JAVACMD}" "${java_opts[@]}"