Привет, я пытаюсь
curl -v --request POST https://example.com --data-urlencode "username=usr]” --data-urlencode "password=[pass]”
передайте вывод в [TOKEN]
поле здесь:
curl -D - --request POST https://example.com --data-urlencode token=[TOKEN]
Однако я не знаком с JSON, так как мой вывод для первой команды выглядит так:
{
"token": "value_of_token"
}
Как бы мне просто взять "value_of_token"
и заставить это быть [TOKEN]
?
решение1
Чтобы наиболее эффективно использовать только value_of_token
вывод команды curl
, передайте вывод в одну sed
команду (редактор потока). Используйте подстановку команд $()
для сохранения вывода в переменной оболочки:
token=$(curl ... | sed -n '/ *"token": *"/ { s///; s/".*//; p; }')
Затем вы можете сослаться на переменную token
как на параметр второй curl
команды:
curl ... token="$token"
Пояснение к sed
команде:
sed -n '/ *"token" *: *"/ { s///; s/".*//; p; q; }'
-n
опцияsed
говоритнетраспечатать каждую входную строку/ *"token" *: *"/
обращается к строке, содержащей значение. Этот шаблон (регулярное выражение) соответствует всему началу строки, вплоть до первой двойной кавычки, ограничивающей значение токена, включая ее.{
начать командный блок, который будет применен к адресованной строке.s///;
команда sed для удаления того, что было ранее сопоставлено (в части адреса). Строка ("pattern space") теперь выглядит так:value_of_token"
s/".*//
Команда sed для удаления оставшейся двойной кавычки ("
) и всего, что находится после нее.p
Команда sed для печати текущей (отредактированной) строки (вsed
терминологии «шаблонное пространство»).q
Немедленно завершить работу скрипта sed без дальнейшей обработки ввода.'}' завершает командный блок.
Например,
$ echo '
{
"token": "value_of_token"
}
' | sed -n '/ *"token" *: *"/ { s///; s/".*//; p; }'
value_of_token
$
Этот метод гораздо эффективнее, чем объединение 4 других команд для достижения того же результата. Эта sed
команда предполагает, что во входных данных JSON нет символов табуляции. Если табуляция есть, sed
команду необходимо будет изменить.
решение2
Во-первых, обратите внимание, что мне пришлось заменить URL-адрес, указанный в ваших командах, <URL>
потому что StackExchange посчитал, что я рассылаю спам, и не разрешил мне публиковать сообщения.
Хорошо, у вас есть два вопроса:
1) Как взять вывод одной команды и сделать его аргументом другой команды?
ответ: Наиболее каноническим методом будет использование подстановки команд оболочки, путем замены вашего аргумента во второй команде следующим образом $( <first command> )
:
curl -D - --request POST <URL> --data-urlencode token=$( curl -v --request POST <URL> --data-urlencode "username=usr]” --data-urlencode "password=[pass]” )
Однако для удобства чтения вам действительно следует сделать это в отдельных строках, сохранив вывод первой команды и повторно используя его следующим образом:
token=$( curl -v --request POST <URL> --data-urlencode "username=usr]” --data-urlencode "password=[pass]” )
curl -D - --request POST <URL> --data-urlencode token="$token"
Кроме того, для полноты картины и поскольку вы конкретно спрашивали, как «передавать по конвейеру», вы можете использовать команду xargs вместо подстановки команд оболочки:
curl -v --request POST <URL> --data-urlencode "username=usr]” --data-urlencode "password=[pass]” | xargs "curl -D - --request POST <URL> --data-urlencode token="{}
Однако, как вы отметили, вывод первой команды не совсем то, что вы ищете в качестве токена; таким образом, приведенные выше решения не будут работать так, как вы ожидаете, что подводит нас к вашему следующему вопросу:
2) Как можно выделить только «value_of_token» из всего вывода JSON?
Не вдаваясь в подробности JSON API, простая конвейеризация grep, head и cut должна справиться с этой задачей:
token=$( curl -v --request POST <URL> --data-urlencode "username=usr]” --data-urlencode "password=[pass]” ) | grep '"token":' | head -1 | cut -d ':' -f 2 | cut -d '"' -f 2
curl -D - --request POST <URL> --data-urlencode token="$token"
Обратите внимание, что это head -1
сделано только на тот случай, если на выходе окажется несколько строк токенов; в этом случае будет использоваться только первая.
Вы должны знать, что это не очень надежное решение, если это приложение важно. Если это так, вам действительно следует проверить код возврата и провести более обширную проверку вывода первой команды curl, чтобы не получить неожиданных результатов; но это потребует более крупного скрипта и выходит за рамки этого вопроса.