curl: добавить строку как опцию в bash

curl: добавить строку как опцию в bash

Я хотел бы передать переменную строку в параметры команды в curl.

if [ ! -z ${picture} ]; then APISTRING+="--data-urlencode \"picture=${picture}\" ";fi
if [ ! -z ${additional} ]; then APISTRING+="--data-urlencode \"additional_info="${additional}"\" ";fi

Таким образом, если picture и additional не пустые, $APISTRING должен быть:

--data-urlencode "picture=someinfo"  --data-urlencode "additional_info=additional infos here"

Но когда я звоню curl

curl -v -X "POST" --url "https://example.org/api" -H "Content-Type: application/x-www-form-urlencoded; charset=utf-8" "${APISTRING}"

Выдает ошибку типа

curl: опция --data-urlencode "picture=someinfo" --data-urlencode "additional_info=дополнительная информация здесь": неизвестно

Есть ли у кого-нибудь идеи, как с этим справиться?

решение1

Вставка кавычек в значение переменной, например, APISTRING+="--data-urlencode \"picture=${picture}\" "не работает правильно. Когда вы пытаетесь использовать $APISTRING, bash анализирует кавычки перед расширением значения переменной и не выполняет повторное сканирование на предмет «новых» кавычек после расширения. В результате кавычки рассматриваются как часть строки, а не как разделители вокруг строки.

Лучшим решением для таких случаев является использование массива для хранения параметров команды:

APISTRING=()
if [ ! -z ${picture} ]; then APISTRING+=(--data-urlencode "picture=${picture}");fi
if [ ! -z ${additional} ]; then APISTRING+=(--data-urlencode "additional_info=${additional}");fi
curl -v -X "POST" --url "https://example.org/api" -H "Content-Type: application/x-www-form-urlencoded; charset=utf-8" "${APISTRING[@]}"

Обратите внимание, что массивы доступны не во всех оболочках POSIX, поэтому их следует использовать только в скриптах, для которых вы явно используете bash (т. е. в комбинации либо , #!/bin/bashлибо #!/usr/bin/env bash,нет #!/bin/sh). Кроме того, синтаксис очень придирчив: не пропускайте ни одной скобки в присваиваниях, двойные кавычки или при [@]расширении массива.

Кстати, есть еще одно возможное решение. Вместо того, чтобы заранее накапливать необязательные опции, вы можете использоватьусловное расширениевключить их на месте:

curl -v -X "POST" --url "https://example.org/api" -H "Content-Type: application/x-www-form-urlencoded; charset=utf-8" \
    ${picture:+ --data-urlencode "picture=${picture}"} \
    ${additional:+ --data-urlencode "additional_info=${additional}"}

Здесь :+расширение сообщает bash о необходимости проверить, является ли переменная непустой, и если это так, то не использовать ее, а использовать альтернативное значение: заключенную в кавычки версию переменной с соответствующим префиксом.

решение2

У вас есть лишние кавычки в "${APISTRING}":

исправить:

curl -v -X "POST" --url "https://example.org/api" -H "Content-Type: application/x-www-form-urlencoded; charset=utf-8" ${APISTRING}

Связанный контент