将数组参数传递给 zsh 中的 bash 脚本

Passing an array argument to a bash script in zsh

我正在尝试创建一个 zsh 别名,它将 运行 一个 bash 环境文件(调用 environment 来设置一些环境变量)然后 运行 一个命令 foo 在那个环境中,使用我用来调用别名的参数。问题是有时我会和其中的空格发生争执,我一直无法弄清楚如何正确通过。

这是我试过的别名示例:

foo() {
    set -x
    bash -c "source environment && foo $@"
}

当我这样称呼它时:

foo launch --name "this is a test"

它没有正确地通过 "this is a test" 参数。

这是错误前的示例输出:

bash -c 'source environment && foo launch' --name 'this is a test'

为什么会这样

"$@" 作为字符串的一部分展开时,该字符串的前后部分将添加到 "$@" 列表中的第一项,并附加到 该列表中的最后一个 项。

所以,当你 运行:

bash -c "source environment && foo $@"

..."$@" 包含列表 launch --name this is a test,你得到的是:

bash -c "source environment && foo launch" --name 'this is a test'

只有 launch——第一个数组元素——成为被解析为源代码的 bash -c 参数的一部分;数组的其他成员然后在被调用的 bash 的副本中填写 [=23=]</code> 等。因为代码 <code>source environment && foo launch 没有查看 [=23=]</code> 等,这些参数随后被忽略。</p> <hr /> <h1>如何修复</h1> <p>在要作为文字代码执行的字符串周围使用 single-quotes。应该从该代码中保留参数 out-of-band。因此,在每个参数开始和结束的地方添加换行符(可能过多)视觉清晰度:</p> <pre><code>foo() { set -x bash \ -xc \ 'source environment && foo "$@"' \ "[=12=]" \ "$@" }

当您使用上述函数定义在 zsh 中调用 foo "first argument" "second argument" 时(假设这是从名为 yourscriptname 的脚本中调用的,并且适当填写 [=23=]):

bash -xc 'source environment && foo "$@"' yourscriptname "first argument" "second argument"

...如果我们将其视为 JSON-ish 伪代码,它是一个具有以下内容的参数向量:

[
  "bash",                             # shell to run
  "-xc",                              # -x: enable tracing; -c: next argument is code
  "source environment && foo \"$@\"", # actual code to run
  "yourscriptname",                   # new [=14=] value when that code is running
  "first argument",                   #  value when that code is running
  "second argument"                   #  value when that code is running
]

这正是我们想要的。 bash 是 运行ning 代码,它使用 "$@" 扩展到它本身传递的参数列表,并且该参数列表从 [=61] 的代码中保留 out-of-band =] 所以你没有注入漏洞。