2017-01-17 4 views
2

У меня есть локон запрос, как это:Как проверить запрос curl в скрипте bash?

curl -s -u $user:$password -X GET -H "Content-Type: application/json" $url 

который возвращает JSON в качестве ответа. Поэтому я проанализирую ответ, используя jq, чтобы получить некоторые конкретные данные. Примерно так:

curl -s -u $user:$password -X GET -H "Content-Type: application/json" $url | jq '<expression>' 

Теперь, если запрос на завивание не работает, очевидно, что операция разбора вызывает уродливую ошибку. Я хочу избежать этого. Как сначала сохранить ответ, а затем проанализировать его, если запрос будет успешным. Я не хочу отображать весь ответ json. Также, если я добавлю -w "%{http_code}" в свой запрос, он добавит код состояния с ответом JSON, который испортит разбор. Как это решить? Я в основном хочу сначала проверить, успешный ли запрос зависания или нет, затем получить ответ JSON и проанализировать его. Я также хочу получить код состояния, так что если он не сработает, я смогу отобразить код состояния. Но код состояния теперь запутывается с ответом json.

+0

Несвязанный nit: вы, вероятно, должны были сказать «Принять:», а не «Тип содержимого». –

ответ

2

Вы можете комбинировать --write и --fail варианты:

# separating the (verbose) curl options into an array for readability 
curl_args=(
    --write "%{http_code}\n" 
    --fail 
    --silent 
    --user "$user:$password" 
    --request GET 
    --header "Content-Type: application/json" 
) 

if ! output=$(curl "${curl_args[@]}" "$url"); then 
    echo "Failure: code=$output" 
else 
    # remove the "http_code" line from the end of the output, and parse it 
    sed '$d' <<<"$output" | jq '...' 
fi  

Также обратите внимание: quote your variables!

+0

Зачем вам нужен http_code, если вы доверяете '--fail' для выхода с ошибкой при ошибке (ответ 4xx или 5xx)? –

+0

Потому что OP хочет код –

+1

Красиво сделано; Я предлагаю 'sed '$ d'', потому что он переносимый (' Q' - функция, специфичная для GNU). @CharlesDuffy: Обратите внимание, что '--silent' подавляет сообщение об ошибке, обычно выводимое' --fail', которое будет включать код состояния, но '--silent' необходим для подавления индикатора выполнения. – mklement0

0

Я нашел ответ Гленна Джекмана хорошо, но немного смущенно написал, поэтому я переписал его и изменил его, чтобы использовать его как более безопасную альтернативу curl | jq.

#!/bin/bash 
# call this with normal curl arguments, especially url argument, e.g. 
# safecurl.sh "http://example.com:8080/something/" 
# separating the (verbose) curl options into an array for readability 
curl_args=(
    -H 'Accept:application/json' 
    -H 'Content-Type:application/json' 
    --write '\n%{http_code}\n' 
    --fail 
    --silent 
) 
echo "${curl_args[@]}" 
# prepend some arguments, but pass on whatever arguments this script was called with 
output=$(curl "${curl_args[@]}" "[email protected]") 
return_code=$? 
if [ 0 -eq $return_code ]; then 
    # remove the "http_code" line from the end of the output, and parse it 
    echo "$output" | sed '$d' | jq . 
else 
    # echo to stderr so further piping to jq will process empty output 
    >&2 echo "Failure: code=$output" 
fi 

Примечание: Этот код не проверяет службы, которые игнорируют запрашиваемый тип контента и отвечают с помощью HTML. Для этого вам нужно протестировать grep -l '</html>'.