Использование curl POST с переменными, определенными в функциях bash script
Когда я эхо, я получаю это, который запускается, когда я ввожу его в терминал
curl -i \
-H "Accept: application/json" \
-H "Content-Type:application/json" \
-X POST --data '{"account":{"email":"[email protected]","screenName":"akdgdtk","type":"NIKE","passwordSettings":{"password":"Starwars1","passwordConfirm":"Starwars1"}},"firstName":"Test","lastName":"User","middleName":"ObiWan","locale":"en_US","registrationSiteId":"520","receiveEmail":"false","dateOfBirth":"1984-12-25","mobileNumber":"9175555555","gender":"male","fuelActivationDate":"2010-10-22","postalCode":"10022","country":"US","city":"Beverton","state":"OR","bio":"This is a test user","jpFirstNameKana":"unsure","jpLastNameKana":"ofthis","height":"80","weight":"175","distanceUnit":"MILES","weightUnit":"POUNDS","heightUnit":"FT/INCHES"}' https://xxx:[email protected]/xxxxx/xxxx/xxxx
Но при запуске в файле bash script я получаю эту ошибку
curl: (6) Could not resolve host: application; nodename nor servname provided, or not known
curl: (6) Could not resolve host: is; nodename nor servname provided, or not known
curl: (6) Could not resolve host: a; nodename nor servname provided, or not known
curl: (6) Could not resolve host: test; nodename nor servname provided, or not known
curl: (3) [globbing] unmatched close brace/bracket at pos 158
это код в файле
curl -i \
-H '"'Accept: application/json'"' \
-H '"'Content-Type:application/json'"' \
-X POST --data "'"'{"account":{"email":"'$email'","screenName":"'$screenName'","type":"'$theType'","passwordSettings":{"password":"'$password'","passwordConfirm":"'$password'"}},"firstName":"'$firstName'","lastName":"'$lastName'","middleName":"'$middleName'","locale":"'$locale'","registrationSiteId":"'$registrationSiteId'","receiveEmail":"'$receiveEmail'","dateOfBirth":"'$dob'","mobileNumber":"'$mobileNumber'","gender":"'$gender'","fuelActivationDate":"'$fuelActivationDate'","postalCode":"'$postalCode'","country":"'$country'","city":"'$city'","state":"'$state'","bio":"'$bio'","jpFirstNameKana":"'$jpFirstNameKana'","jpLastNameKana":"'$jpLastNameKana'","height":"'$height'","weight":"'$weight'","distanceUnit":"MILES","weightUnit":"POUNDS","heightUnit":"FT/INCHES"}'"'" "https://xxx:[email protected]/xxxxx/xxxx/xxxx"
Я предполагаю, что проблема с моими кавычками, но я много играл с ними, и у меня были подобные ошибки. Все переменные определяются с помощью различных функций в фактическом script
Ответы
Ответ 1
Вам не нужно передавать кавычки, содержащие пользовательские заголовки. Кроме того, ваши переменные в середине аргумента data
должны быть в кавычках.
Сначала напишите функцию, которая генерирует данные поста вашего скрипта. Это избавит вас от всех видов головной боли, связанной с цитированием оболочки, и облегчит чтение сценария сопровождения, чем подача данных поста в строку вызова curl, как при вашей попытке:
generate_post_data()
{
cat <<EOF
{
"account": {
"email": "$email",
"screenName": "$screenName",
"type": "$theType",
"passwordSettings": {
"password": "$password",
"passwordConfirm": "$password"
}
},
"firstName": "$firstName",
"lastName": "$lastName",
"middleName": "$middleName",
"locale": "$locale",
"registrationSiteId": "$registrationSiteId",
"receiveEmail": "$receiveEmail",
"dateOfBirth": "$dob",
"mobileNumber": "$mobileNumber",
"gender": "$gender",
"fuelActivationDate": "$fuelActivationDate",
"postalCode": "$postalCode",
"country": "$country",
"city": "$city",
"state": "$state",
"bio": "$bio",
"jpFirstNameKana": "$jpFirstNameKana",
"jpLastNameKana": "$jpLastNameKana",
"height": "$height",
"weight": "$weight",
"distanceUnit": "MILES",
"weightUnit": "POUNDS",
"heightUnit": "FT/INCHES"
}
EOF
}
Затем легко использовать эту функцию при вызове curl:
curl -i \
-H "Accept: application/json" \
-H "Content-Type:application/json" \
-X POST --data "$(generate_post_data)" "https://xxx:[email protected]/xxxxx/xxxx/xxxx"
Сказал, вот несколько пояснений о правилах цитирования оболочки:
Двойные кавычки в аргументах -H
(как в -H "foo bar"
) говорят bash хранить то, что внутри, как один аргумент (даже если он содержит пробелы).
Одиночные кавычки в аргументе --data
(как в --data 'foo bar'
) делают то же самое, за исключением того, что они передают весь текст (включая символы двойной кавычки и знак доллара).
Чтобы вставить переменную в середину текста в одинарных кавычках, необходимо завершить одинарную кавычку, затем объединить ее с переменной в двойных кавычках и заново открыть одинарную кавычку, чтобы продолжить текст: 'foo bar'"$variable"'more foo'
.
Ответ 2
Решение, протестированное с помощью https://httpbin.org/ и inline bash script
1. Для переменных без пробелов в нем, т.е. 1
:
Просто добавьте '
до и после $variable
при замене желаемого строка
for i in {1..3}; do \
curl -X POST -H "Content-Type: application/json" -d \
'{"number":"'$i'"}' "https://httpbin.org/post"; \
done
2. Для ввода с пробелами:
Переменная Wrap с дополнительным "
i.e. "el a"
:
declare -a arr=("el a" "el b" "el c"); for i in "${arr[@]}"; do \
curl -X POST -H "Content-Type: application/json" -d \
'{"elem":"'"$i"'"}' "https://httpbin.org/post"; \
done
Ничего себе работает:)
Ответ 3
Curl может отправлять двоичные данные из файла, поэтому я использую замену процессов и использую дескрипторы файлов всякий раз, когда мне нужно размещать что-то неприятное с завитом и все еще хочу получить доступ к vars в текущей оболочке. Что-то вроде:
curl "http://localhost:8080" \
-H "Accept: application/json" \
-H "Content-Type:application/json" \
--data @<(cat <<EOF
{
"me": "$USER",
"something": $(date +%s)
}
EOF
)
Это выглядит как --data @/dev/fd/<some number>
, который просто обрабатывается как обычный файл. В любом случае, если вы хотите, чтобы он работал локально, просто запустите nc -l 8080
сначала, а в другой оболочке отключите указанную выше команду. Вы увидите что-то вроде:
POST / HTTP/1.1
Host: localhost:8080
User-Agent: curl/7.43.0
Accept: application/json
Content-Type:application/json
Content-Length: 43
{ "me": "username", "something": 1465057519 }
Как вы можете видеть, вы можете вызывать субголовы и еще что-то, а также справочные вары в heredoc. Счастливая хакерская надежда, это помогает с '"'"'""""'''""''
.
Ответ 4
Несколько лет спустя, но это может помочь кому-то, если вы используете замену eval или backtick:
postDataJson="{\"guid\":\"$guid\",\"auth_token\":\"$token\"}"
Использование sed для удаления цитат из начала и конца ответа
$(curl --silent -H "Content-Type: application/json" https://${target_host}/runs/get-work -d ${postDataJson} | sed -e 's/^"//' -e 's/"$//')
Ответ 5
- информация от сэра Атоса работала отлично!
Вот как мне пришлось использовать его в моем завитке script для couchDB. Это действительно помогло
много. Спасибо!
bin/curl -X PUT "db_domain_name_:5984/_config/vhosts/$1.couchdb" -d '"/'"$1"'/"' --user "admin:*****"
Ответ 6
Существующие ответы указывают на то, что curl может отправлять данные из файла и использовать heredocs, чтобы избежать чрезмерного экранирования кавычек и четко разбить JSON на новые строки. Однако нет необходимости определять функцию или захватывать вывод от cat, потому что curl может публиковать данные из стандартного ввода. Я нахожу эту форму очень удобочитаемой:
curl -X POST -H 'Content-Type:application/json' --data '[email protected]' ${API_URL} << EOF
{
"account": {
"email": "$email",
"screenName": "$screenName",
"type": "$theType",
"passwordSettings": {
"password": "$password",
"passwordConfirm": "$password"
}
},
"firstName": "$firstName",
"lastName": "$lastName",
"middleName": "$middleName",
"locale": "$locale",
"registrationSiteId": "$registrationSiteId",
"receiveEmail": "$receiveEmail",
"dateOfBirth": "$dob",
"mobileNumber": "$mobileNumber",
"gender": "$gender",
"fuelActivationDate": "$fuelActivationDate",
"postalCode": "$postalCode",
"country": "$country",
"city": "$city",
"state": "$state",
"bio": "$bio",
"jpFirstNameKana": "$jpFirstNameKana",
"jpLastNameKana": "$jpLastNameKana",
"height": "$height",
"weight": "$weight",
"distanceUnit": "MILES",
"weightUnit": "POUNDS",
"heightUnit": "FT/INCHES"
}
EOF
Ответ 7
Вот что на самом деле работало для меня, после указания из ответов здесь:
export BASH_VARIABLE="[1,2,3]"
curl http://localhost:8080/path -d "$(cat <<EOF
{
"name": $BASH_VARIABLE,
"something": [
"value1",
"value2",
"value3"
]
}
EOF
)" -H 'Content-Type: application/json'