Я хотел бы передать переменную строку в параметры команды в 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}