chocksaway
chocksaway

Reputation: 900

BASH shell script echo to output on same line

I have a simple BASH shell script which checks the HTTP response code of a curl command. The logic is fine, but I am stuck on "simply" printing out the "output".

I am using GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu)

I would like to output the URL with a tab - then the 404|200|501|502 response. For example:

http://www.google.co.uk<tab>200

I am also getting a strange error where the "http" part of a URL is being overwritten with the 200|404|501|502. Is there a basic BASH shell scripting (feature) which I am not using?

thanks

Miles.

#!/bin/bash

NAMES=`cat $1`
for i in $NAMES
do

    URL=$i
    statuscode=`curl -s -I -L $i |grep 'HTTP' | awk '{print $2}'`

    case $statuscode in
    200)
        echo -ne $URL\t$statuscode;;
    301)
        echo -ne "\t $statuscode";;
    302)
        echo -ne "\t $statuscode";;
    404)
        echo -ne "\t $statuscode";;
    esac
done

Upvotes: 4

Views: 30263

Answers (3)

Shawn Chin
Shawn Chin

Reputation: 86844

I'm taking a stab here, but I think what's confusing you is the fact that curl is sometimes returning more than one header info (hence more than one status code) when the initial request gets redirected.

For example:

[me@hoe]$ curl -sIL www.google.com | awk '/HTTP/{print $2}'
302
200

When you're printing that in a loop, it would appear that the second status code has become part of the next URL.

If this is indeed your problem, then there are several ways to solve this depending on what you're trying to achieve.

  1. If you don't want to follow redirections, simple leave out the -L option in curl

    statuscode=$(curl -sI $i | awk '/HTTP/{print $2}')
    
  2. To take only the last status code, simply pipe the whole command to tail -n1 to take only the last one.

    statuscode=$(curl -sI $i | awk '/HTTP/{print $2}' | tail -n1)
    
  3. To show all codes in the order, replace all linebreaks with spaces

    statuscode=$(curl -sI $i | awk '/HTTP/{print $2}' | tr "\n" " ")
    

For example, using the 3rd scenario:

[me@home]$ cat script.sh
#!/bin/bash
for URL in www.stackoverflow.com stackoverflow.com stackoverflow.com/xxx 
do
     statuscode=$(curl -siL $i | awk '/^HTTP/{print $2}' | tr '\n' ' ')
     echo -e "${URL}\t${statuscode}"
done

[me@home]$ ./script.sh
www.stackoverflow.com   301 200 
stackoverflow.com       200 
stackoverflow.com/xxx   404 

Upvotes: 0

Lewis Norton
Lewis Norton

Reputation: 7151

From this answer you can use the code

response=$(curl --write-out %{http_code} --silent --output /dev/null servername)


Substituted into your loop this would be

#!/bin/bash

NAMES=`cat $1`
for i in $NAMES
do

    URL=$i
    statuscode=$(curl --write-out %{http_code} --silent --output /dev/null $i)

    case $statuscode in
        200)
            echo -e "$URL\t$statuscode" ;;
        301)
            echo -e "$URL\t$statuscode" ;;
        302)
            echo -e "$URL\t$statuscode" ;;
        404)
            echo -e "$URL\t$statuscode" ;;
        * )
            ;;
    esac
done

I've cleaned up the echo statements too so for each URL there is a new line.

Upvotes: 2

Raihan
Raihan

Reputation: 10395

try

 200)
    echo -ne "$URL\t$statuscode" ;; 

Upvotes: 1

Related Questions