将数组参数传递给 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 =] 所以你没有注入漏洞。
我正在尝试创建一个 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 =] 所以你没有注入漏洞。