使用 shell 'printf',其中格式字符串位于变量中并且没有固定数量的字段占位符?

使用 shell 'printf',其中格式字符串位于变量中并且没有固定数量的字段占位符?

我正在编写一个 shell 函数,它通过 cURL 进行外部 API 调用(外部 API 语法不受我的控制)。我是这样处理的(简化的):

#!/bin/sh

template_get_entry='get_entry:%s'
template_set_entry='set_entry:%s=%s'

curlheaders='-H stuff'
curluri="https://www.domain.com:1234/api.php"

# make an API call to get entry "foo"
call_api "$template_get_entry" "foo"

# make an API call to set entry "foo" to "bar"
call_api "$template_set_entry" "foo" "bar"

call_api() {

  apicmd="$( printf "$1" "$2" "$3" )"
  result="$( eval "/usr/local/bin/curl" "$curlheaders" "-d" "$apicmd" "$curluri" )"
  retcode="$?"

  .....stuff.....

}

这段代码有两个问题。

首先,参数的数量是可变的。如果apicmd使用少于最大参数数调用行定义,则 printf 会将任何多余的命令解释为打印格式字符串的额外实例,以进行附加。我看不出解决这个问题的正确方法。

其次,因为我使用了 eval,这会产生 eval 的连锁问题,因为 retcode 肯定会从 中获取返回代码,eval而不是从 中获取curl,而且我不知道防止/修复该问题的正确方法。

我应该如何做这样的事情,需要可变数量的参数?

答案1

您可以尝试使用零长度说明符填充格式字符串,直到最大预期参数计数:

template_get_entry='get_entry:%s %0.0s'

答案2

您可以做的是获取格式字符串参数,将其从参数列表中移出,然后使用$@

call_api () {
    fmt=$1
    shift

    apicmd=$( printf "$fmt" "$@" )

    # ...
}

相关内容