1

Hello I am a newby and I cannot understand how the eval command is working here. How many args are being evaluated? What does the \ do here?
Thanks for the help!!!

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}
4

3 回答 3

0

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

"${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设置为任何非空值,则其扩展将替换为-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 中工作。如果这是 for 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[@]}"
于 2013-11-06T14:09:11.223 回答
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 [arguments] 将参数连接在一起形成一个命令,然后读取并执行该命令,并将其退出状态作为 eval 的退出状态返回。如果没有参数或只有空参数,则返回状态为零。

我不太明白为什么不使用'eval'而不使用相同的命令,因为它的结果没有被使用(由于你的代码)。

顺便说一句,您总是可以通过打印所有 bash 命令的跟踪来查看脚本中发生了什么。您可以在外部进行,只需运行

bash -x script.sh

或者您可以修改脚本本身。就放

set -x

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

于 2013-11-06T10:46:21.820 回答
0

About shell bulletin eval:

当命令行包含需要由 shell 评估的内容时,eval很有用。eval将一个字符串作为它的参数,并像在命令行上键入该字符串一样对其进行评估。

PS:应谨慎使用。

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

于 2013-11-06T10:28:53.367 回答