2

我想执行一个需要 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解决了这个问题,但我不想使用它(因为如果我执行多次这样的调用需要时间)。

4

2 回答 2

3

OP 最初标记了 question ,然后删除了该标记。请参阅 Charles Duffy 的 POSIX shell 解决方案的最佳答案!下面的解决方案使用数组,仅适用于


您不应将数据放在这样的字符串中,而应放在数组中。顺便说一句,您的函数中缺少一些引号:

func() {
    echo "---$1---"
    echo "---$2---"
    echo "---$3---"
}

或更好(优于printfecho

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---
于 2015-02-16T13:56:21.943 回答
3

如果特性(如数组)没有使 bash 比 POSIX sh 更具表现力,那么就没有理由添加它们。:)

也就是说,您可以通过覆盖"$@"您的需求来解决它:

set -- 111 "222 222" 333
printf '%s\n' "$@"

...将打印...

111
222 222
333

如果您需要逐步构建参数列表,您可以多次调用setwith"$@"作为第一个参数(确保您遵守引号!):

set -- 111
set -- "$@" "222 222"
set -- "$@" 333
printf '%s\n' "$@"

...将打印...

111
222 222
333
于 2015-02-16T14:01:38.807 回答