gpt4 book ai didi

Bash 在引用参数列表时插入额外的、不正确的单引号

转载 作者:行者123 更新时间:2023-11-29 09:09:37 25 4
gpt4 key购买 nike

我正在尝试制作一个程序,该程序将使用特定参数运行 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"。是什么导致添加这些额外的引号,我该如何解决这个问题以获得我想要的结果?

最佳答案

arguments="${*:2}"
mvn exec:java -Dexec.mainClass="$1" -Dexec.args="$arguments"

参见 BashFAQ #50以获得完整的解释。也就是说:

"$@" 维持 argv 数组元素之间的分割——也就是说 --foo="$@",当 设置 - - Hello World ,解析为"--foo=hello""world"

"$*" 将 argv 数组元素与它们之间的 IFS 的第一个字符组合在一起,默认情况下是一个空格。

$*,没有双引号,做同样的事情,但不能防止字符串拆分或 glob 扩展,从而组合所有参数,但随后允许 shell 再次将它们拆分(并扩展它们包含的 globs)——这种行为很少是可取的。

arguments="\"${*:2}\"" 创建一个字符串 -- "hello world"。当您运行 -Dexec.args=$arguments 时,这会经历几个处理阶段(不包括与您当前数据集无关的阶段,例如 glob 扩展):

  • 进行语法分析。 在这个阶段,并且只有在这个阶段,shell 才会确定引用哪些字符以及如何引用。因为 -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(您不应该!),只需省略它们,并仅使用句法引号,如本答案顶部示例中所做的那样。

关于Bash 在引用参数列表时插入额外的、不正确的单引号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24744164/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com