我正在尝试使用某些参数创建一个运行Maven的程序。
它基本上是这样做的:
ARGUMENTS=\""${@:2}"\"
mvn exec:java -Dexec.mainClass=$1 -Dexec.args=$ARGUMENTS
因此运行./myScript.sh a b c
会导致运行:
mvn exec:java -Dexec.mainClass=a -Dexec.args="b c"
但Maven正在抛出一个未知生命周期的错误。在那里投掷set -x
告诉我该命令实际上变成了:
mvn exec:java -Dexec.mainClass=a '-Dexec.args="b' 'c"'
回应$ARGUMENTS
会给出预期的"b c"
。是什么导致添加这些额外的报价,我该如何解决这个问题以获得我的预期结果?
答案 0 :(得分:5)
arguments="${*:2}"
mvn exec:java -Dexec.mainClass="$1" -Dexec.args="$arguments"
有关完整说明,请参阅BashFAQ #50。那说:
"$@"
维护argv数组元素之间的分割 - 也就是说--foo="$@"
,当set -- hello world
解析为"--foo=hello" "world"
时。
"$*"
将argv数组元素与它们之间的第一个IFS
字符组合在一起,默认情况下为空格。
$*
执行相同的但是无法阻止字符串拆分或全局扩展,因此组合所有参数,但随后允许shell再次将它们拆分(并扩展它们包含的globs) - 一种很少需要的行为。
arguments="\"${*:2}\""
创建一个字符串 - "hello world"
。运行-Dexec.args=$arguments
时,会经历几个处理阶段(不包括与当前数据集无关的阶段,例如glob扩展):
-Dexec.args=$arguments
中不存在字面引号,因此唯一的扩展记录为不带引号。-Dexec.args="hello world"
-Dexec.args="hello
是一个单词,而world"
是一个单词。将此与正确用法进行比较,-Dexec.args="$arguments"
(或其有效等效值,"-Dexec.args=$arguments"
)。此时:
$arguments
周围的双引号,并将扩展标记为双引号。arguments
数组中仍然包含字面引号,则它们会被替换为数据,使-Dexec.args="hello world"
将文字数据传递给Maven,包括引号字符本身如果您不希望将文字引号字符传递给Maven(并且您不应该这样做),只需省略它们,并仅使用语法引号,如本答案顶部的示例所示。
答案 1 :(得分:3)
似乎是引用问题。尝试使用BASH数组:
arr=( "$@" )
mvn exec:java -Dexec.mainClass="$1" -Dexec.args="${arr[*]:1}"