Shell How to check presence of a host in shell script

Can someone show me how to check the presence of a host in a shell script with a timeout of half a minute?

I just can't come up with a simple way of doing it.
 
What about using an rc.d script and let rcoder(8) do its job.
Use a keyword to determine when it starts. For example:
REQUIRE: LOGIN
This would start the script once FreeBSD hits the login prompt.

For the timeout simply add sleep <number of seconds>

I am assuming here that you are trying to script usbmodeswitch to startup your cellular modem.
 
I guess, the answer depends on several things:
  • presence of any host or a particular host?
  • access it with ping, ssh, http etc?
E.g. consider a host you want to access from your script using curl(), but its web server died, so you'll get timeout, but you can still ping it.
 
I am assuming here that you are trying to script usbmodeswitch to startup your cellular modem.

No, I'm trying to put together a script to do a fully automated install of FreeBSD booting from a PXE server where the installation image is somewhere on the LAN.

I'm having problems incorporating IP addresses in the script.
 
I guess, the answer depends on several things:
  • presence of any host or a particular host?
  • access it with ping, ssh, http etc?
E.g. consider a host you want to access from your script using curl(), but its web server died, so you'll get timeout, but you can still ping it.

I just want to know if a particular host is available using ping.
 
Here is a bit of code I found which seems to do basically what I want:-
Code:
!/bin/sh
server=192.168.1.1
ping_response=-1
while [ "0" != "\$ping_response" ]; do
  echo Waiting to let network connections settle ...
  sleep 1
  ping -qc 1 $server > /dev/null
  ping_response=\$?
done

I can't figure out how to incorporate a timeout. The assumption is that the sever will be available.
 
For a timeout of about 30-60 seconds, based on your example:
Code:
!/bin/sh
server=192.168.1.1
to_limit=30 #--- 30 retry timeout limit
to_count=0
ping_response=-1
while [ "0" != "$ping_response" ]&&[ $to_count -lt $to_limit ]; do
  echo Waiting to let network connections settle ...
  sleep 1 #--- 1 second timeout
  ping -qc 1 -W 0 $server > /dev/null 2>&1
  ping_response=$?
  if [ "0" != "$ping_response" ]; then
    to_count=$(($to_count+1))
  fi
done
if [ "0" = "$ping_response" ]; then
  echo "Response received from "$server" after "$to_count" retries."
else
  echo "No response from "$server" after "$to_count" retries."
fi
1. The backslash characters had to come out because "\$ping_response" != "$ping_response"

2. -W 0 in the ping syntax is necessary to avoid unwanted additional wait times.

3. 2>$1 is needed to avoid error output from ping, such as "ping: sendto: Host is down"

4. This specifies a 30 "second" timeout, but in practice, the 30 retries may actually take as much time as 30 additional seconds to complete, due to additional overhead, and depending on your CPU speed.
 
First of all, you must not escape the dollar sign in your script. Otherwise it will assign the actual string "$?" to your variable.
Secondly, ping() provides a timeout setting:
Code:
-t timeout
             Specify a timeout, in seconds, before ping exits regardless of
             how many packets have been received.
If it was a timeout the exit code will be 2.
 
First of all, you must not escape the dollar sign in your script. Otherwise it will assign the actual string "$?" to your variable.

Actually I did need it. It took quite a lot of time trying to get it to work. I think it was because the code was part of a here document which I guess interprets dollar signs differently.
 
It's really simple, you don't even need a loop. With -ot 30 it tries to ping the host for 30 seconds. As soon as one reply is received, it exits with exit code 0 (true). If it didn't receivce a reply within 30 seconds, it exits with exit code 2 (false). So you can simply use this snipped in your script:
Code:
...
if ping -ot 30 $server >/dev/null 2>&1 ; then
        echo "Server is alive."
else
        echo "No response from server."
fi
...
 
Back
Top