형식 문자열이 변수에 있고 고정된 수의 필드 자리 표시자가 없는 쉘 'printf'를 사용합니까?

형식 문자열이 변수에 있고 고정된 수의 필드 자리 표시자가 없는 쉘 'printf'를 사용합니까?

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을 사용하고 있기 때문에 이로 인해 eval과 관련된 문제가 발생합니다. 왜냐하면 retcode는 확실히 eval이 아닌 eval 에서 반환 코드를 가져오고 curl해당 문제를 예방/수정하는 적절한 방법을 모르기 때문입니다.

가변 개수의 인수가 필요한 이와 같은 작업을 어떻게 수행해야 합니까?

답변1

최대 예상 인수 수까지 길이가 0인 지정자를 사용하여 형식 문자열을 채울 수 있습니다.

template_get_entry='get_entry:%s %0.0s'

답변2

당신이 할 수 있는 일은 형식 문자열 매개변수를 가져와 매개변수 목록 밖으로 이동하고 다음을 사용하는 것입니다 $@.

call_api () {
    fmt=$1
    shift

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

    # ...
}

관련 정보