1

I'm doing ad-hoc profiling on a web service that seems to maintain some state and get slower and slower until eventually things start timing out. I have a simple script that will expose this behavior:

while true
do
    RESPONSE_CODE=$( curl --config curl.config )

    if [ "$RESPONSE_CODE" -eq "200" ]; then
        echo SUCCESS
    else
        echo FAILURE
    fi
done

Along with some headers, cookies, post data, url, etc. curl.config in particular has the lines:

silent
output = /dev/null
write-out = "%{http_code}"

So the only output from curl should be the HTTP status code.

This works fine. What I'd like to do is something like this:

{ time -p RESPONSE_CODE=$(curl --config curl.config) ; } 2>&1 | awk '/real/{print $2;}'

to get a running printout of how long these queries actually take, while still saving curl's output for use in my test. But that doesn't work.

How can I capture the http status from curl AND grab the output of time so I can process both?

2 Answers 2

1

As written:

RESPONSE_CODE = $( curl --config curl.config )

you have spaces around the assignment which simply does not work in shell (it tries to execute a command RESPONSE_CODE with = as the first argument, etc. You need:

RESPONSE_CODE=$( curl --config curl.config )

The time built-in is hard to redirect. Since you need both HTTP status and real time, you will have to do something to capture both values. One possibility is:

set -- $( (time -p -- curl --config curl.config ) 2>&1 |
         awk '/real/{print $2} /^[0-9]+$/{print}')

which will set $1 and $2. Another is array assignment:

data=( $( (time -p -- curl --config curl.config ) 2>&1 |
         awk '/real/{print $2} /^[0-9]+$/{print}') )

The HTTP response code should appear before the time.

(Tested using sh -c 'echo 200; sleep 1' in lieu of curl --config curl.config.)

Sign up to request clarification or add additional context in comments.

3 Comments

You're right about the variable assignment - it was correct in the script, and I flubbed it while redacting the script to post here. Question updated.
That did the trick, aside from time on OS X lacking the -- option. Thanks!
Interesting note on portability. The absence of support for the -- option in the Mac OS X (BSD?) time command is arguably a bug (it contravenes the POSIX Utility Syntax Guidelines and specifically Guideline 10).
1

This should work if Curl's response is only a single line:

#!/bin/bash
RESPONSE_CODE=''
TIME=''
while read -r TYPE DATA; do
    case "$TYPE" in
    curl)
        RESPONSE_CODE=$DATA
        ;;
    real)
        TIME=$DATA
        ;;
    esac
done < <(exec 2>&1; time -p R=$(curl --config curl.config); echo "curl $R") 

Or use an associative array:

#!/bin/bash
declare -A RESPONSE
while read -r TYPE DATA; do
    RESPONSE[$TYPE]=$DATA
done < <(exec 2>&1; time -p R=$(curl ...); echo "code $R") 
echo "${RESPONSE[code] ${RESPONSE[real]}"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.