bash - Bash 扩展之谜
问题描述
这是 stackoverflow 上一个非常“流行”的话题,不幸的是我在查看其他问题时无法弄清楚这一点。无论如何,让我们考虑以下场景。一个函数得到一堆字符串参数,如下所示:
some_function "give some" "string arguments"
这个函数做的第一件事是将这些参数放入一个数组中,例如 array[0] 给出“给一些”,而 array[1] 给出“字符串参数”
现在假设我有一个字符串数组some_array
并想在其上调用 some_function。我如何“转换”该数组以使其工作?
以下是一些不起作用的示例:
function print_args() {
local arr=( "$@" )
i=0;
for item in "${arr[@]}"
do
echo "[$i] -> '$item'"
(( i++ ))
done
}
echo "example"
print_args "this is" "the desired" "behavior"
echo -e "----------------\n"
some_array=( "\"does NOT\"" "\"seem to\"" "\"work\"" )
stringified_array=$(printf "%s " "${some_array[@]}")
echo "stringified array: [$stringified_array]"
echo "1) passing \$some_array"
print_args $some_array
echo -e "---------------------------\n"
echo "2) passing \"\$some_array\""
print_args "$some_array"
echo -e "---------------------------\n"
echo "3) passing \$stringified_array"
print_args $stringified_array
echo -e "---------------------------\n"
echo "4) passing \"\$stringified_array\""
print_args "$stringified_array"
echo -e "---------------------------\n"
这是输出
example
[0] -> 'this is'
[1] -> 'the desired'
[2] -> 'behavior'
----------------
stringified array: ["does NOT" "seem to" "work" ]
1) passing $some_array
[0] -> '"does'
[1] -> 'NOT"'
---------------------------
2) passing "$some_array"
[0] -> '"does NOT"'
---------------------------
3) passing $stringified_array
[0] -> '"does'
[1] -> 'NOT"'
[2] -> '"seem'
[3] -> 'to"'
[4] -> '"work"'
---------------------------
4) passing "$stringified_array"
[0] -> '"does NOT" "seem to" "work" '
---------------------------
我想我理解 1) 和 2) 并且只是出于绝望才尝试它们。我相信我也理解 4)。现在我的大问题是我不明白 3) 到底发生了什么,更重要的是我如何“字符串化”我的数组以实现我想要的。这里的一个重要说明是,我想尽量避免使用 eval
.
谢谢!
解决方案
您可能希望您说的是 3):
print_args "does NOT" "seem to" "work"
但实际上 3) 相当于:
print_args '"does' 'NOT"' '"seem' 'to"' '"work"'
这是因为未引用的参数变量在传递给函数之前$stringified_array
被拆分为单词。字符串中的双引号只是字符串的一部分,不能用来引用空格。IFS
尝试通过修改示例代码中的 #16-#17 行来查看会发生什么:
16c16
< stringified_array=$(printf "%s " "${some_array[@]}")
---
> stringified_array=$(printf "%s#" "${some_array[@]}")
17a18
> IFS=#
通过分配IFS
一个未出现在字符串中的分隔符,您将能够安全地对数组进行字符串化,尽管还有其他解决方案不会对数组进行字符串化。
希望这可以帮助。
推荐阅读
- azure - 使用 terraform 的 Azure Databricks 工作区
- docker - Docker 抛出“{binary} not found”错误
- logic - 组合逻辑电路图上的黑点代表什么?
- python - 如何以特定方式将数据框转换为 Python 字典?
- python - 从 numpy 数组创建数据框
- c - 可以使用三元运算符在一行中实现按位设置/重置吗?
- signalr - 如何在 SignalR 上正确覆盖调用方法
- python - PySpark 作业的实施模式
- javascript - HTML 中的不同窗口
- modelica - 是否有一个 Block 组件来保持 PID 控制器信号稳定不变 100 秒