我想执行一个需要3个参数的shell脚本。
参数编号2包含带空格的字符串
我想将所有参数放在一个变量中:
Linux:~# kk="\"111\" \"222 222\" \"333\""
Linux:~# echo $kk
"111" "222 222" "333"
现在如果我调用一个函数:
func() {
echo ---$1---
echo ---$2---
echo ---$3---
}
以这种方式使用$ kk变量
func $kk
然后它将返回
Linux:~# func $kk
---"111"---
---"222---
---222"---
我期待得到这个结果
---111---
---222 222---
---333---
如何在不使用eval
的情况下解决此问题?
我知道eval
解决了这个问题,但我不想使用它(因为如果我多次执行此类调用需要时间)。
答案 0 :(得分:3)
OP最初标记了问题bash,然后删除了标记。请参阅Charles Duffy对POSIX shell解决方案的最佳答案!下面的解决方案使用数组,仅适用于bash。
您不应将数据放在这样的字符串中,而应放在数组中。顺便说一下,你在函数中遗漏了一些引号:
func() {
echo "---$1---"
echo "---$2---"
echo "---$3---"
}
或更好(printf
优于echo
):
func() {
printf -- '---%s---\n' "$1"
printf -- '---%s---\n' "$2"
printf -- '---%s---\n' "$3"
}
$ kk=( "111" "222 222" "333" )
$ func "${kk[@]}"
很乐意打印:
---111---
---222 222---
---333---
您甚至可以在参数中包含换行符:
$ kk=( $'one\none' "222 222" $' * three\nthree' )
$ func "${kk[@]}"
---one
one---
---222 222---
--- * three
three---
答案 1 :(得分:3)
如果功能(如数组)没有使bash比POSIX sh更具表现力,那么就没有理由添加它们。 :)
也就是说,您可以通过覆盖"$@"
来满足您的需求:
set -- 111 "222 222" 333
printf '%s\n' "$@"
...将打印...
111
222 222
333
如果您需要逐步构建参数列表,可以使用set
作为第一个参数进行多次调用"$@"
(确保您遵守引号!):
set -- 111
set -- "$@" "222 222"
set -- "$@" 333
printf '%s\n' "$@"
...将打印...
111
222 222
333