1

When I use ping foo.com I either get a response or ping: unknown host foo.com I am using this script to show custom responses

status=$(ping -c 1 foo.com 2> /dev/null)

if [[ status -ne '200' ]]; then
     echo "site found"
    else
     echo "site not found" 
fi

the problem with the above is that, if site is found I get site found response, but if not instead of the error message, I get the default ping: unknown host foo.com

UPDATED.

declare -A websites 
websites=("" "")
    function ping_sites(){
        if [[ $1 != 'all' ]]; then 
            status=$(curl -I  --stderr /dev/null $1 | head -1 | cut -d' ' -f2)
            result=$(ping -c 1 $1 | grep 'bytes from' | cut -d = -f 4 | awk {'print $1'} 2> /dev/null)

            if [[ status -ne '200' ]]; then
                echo -e "$1  $c_red \t $status FAIL $c_none"
            else
                echo -e "$1  $c_green \t $status OK $c_none"
            fi
        else
          ... 

.

ping all 
ping foo.com
trbvm
  • 453
  • 1
  • 4
  • 7
  • The string `status` is not the same as `200` (unless `[[ … ]]` does something excruciatingly weird with the string), so the site will always be found. Did you mean `$?`? – Jonathan Leffler Nov 27 '15 at 21:26
  • @JonathanLeffler sorry, updated. it was `status=$(` – trbvm Nov 27 '15 at 21:32
  • OK; you still need to use `$status` instead of plain-word `status` because the latter is not equal to 200 when converted to a number (it might be equal to 0, though my casual experimentation showed that it wasn't, but that's your best case scenario and not what you meant). – Jonathan Leffler Nov 27 '15 at 21:37
  • @JonathanLeffler yeah, sorry. I copy pasted it from a huge chunk of code, but the main issue is as I have mentioned it, to replace hide the error code so as the default wont be shown – trbvm Nov 27 '15 at 21:39
  • What do you mean by 'error code'? The output from `ping`'s standard output, its standard error, or its exit status — or something else? How does it report 200? Our problem is that we can only debug what you show us, not what you meant to show us. Please review how to create an MCVE ([How to create a Minimal, Complete, and Verifiable Example?](http://stackoverflow.com/help/mcve)) so that we don't have to second guess what your code is. – Jonathan Leffler Nov 27 '15 at 21:40
  • @JonathanLeffler I added a chunk from the actual code enough to avoid guessing. – trbvm Nov 27 '15 at 21:46
  • So in fact the 200 is supposed to be coming from `curl` and not from `ping` at all? This is why it's important to show the real code! (You still need to use `$status` (preferably inside double quotes according to this old fogey, though you may be OK w/o given that it's Bash and the `[[` operation; if it were `[`, the double quotes would be close to mandatory). – Jonathan Leffler Nov 27 '15 at 21:47
  • Sorry, I just assumed "how to hide stderr" would be enough question by its own – trbvm Nov 27 '15 at 21:48
  • OK; it then becomes very close to a duplicate of [How to pipe stderr and not stdout?](https://stackoverflow.com/questions/2342826/how-to-pipe-stderr-and-not-stdout/2342841#2342841). – Jonathan Leffler Nov 27 '15 at 21:51

1 Answers1

3
pingWrap(){
  if ping -c 1 "$1" >/dev/null 2>&1; then
    echo "site found"
  else
    echo "site not found" 
  fi
}
pingWrap foo.com
pingWrap localhost

if ping -c 1 "$1" >/dev/null 2>&1; then suppresses all output and tests the return status of the ping command which is either 0 (success) or something else (failure).

[[ status -ne '200' ]] takes the string status and the string 200, converts each to an integer and tests the two integers for inequality, which is as nonsensical as it sounds.

The return status of a shell command is held in the $? variable and it has nothing to do with HTTP return codes. HTTP runs on top of TCP, and ping doesn't even use TCP.


HTTP Statuses

If the target site is up and speaks HTTP, you can get the http status on stdout with:

httpStatus(){ curl -s -w %{http_code} "$@" -o /dev/null; }

E.g.,

httpStatus google.com #200
httpStatus google.com/secret #301

st="`httpStatus "$1"`" &&
case "$st" in
   301) echo Moved permanently;;
   200) echo Success;;
     *) echo Unknown;;
esac
Community
  • 1
  • 1
Petr Skocik
  • 58,047
  • 6
  • 95
  • 142
  • 1
    Nicely done; your solution is (commendably) POSIX-compliant; just to mention a shorter `bash` alternative for suppressing all output: `&>/dev/null` – mklement0 Nov 27 '15 at 21:24
  • if I use the statement in the line as without [[]] I am getting `line 85: conditional binary operator expected` anway, even the above way does not work as it shows the default error messages anyway. probably missed something – trbvm Nov 27 '15 at 21:28
  • Also, I would still like to get the status code for relate re-use as in to show why a "site is not found" it could be 404, 405 ... – trbvm Nov 27 '15 at 21:31
  • @trbvm Updated the answer. – Petr Skocik Nov 27 '15 at 21:46