Linode.com Forum Forum Index Linode.com Forum
Linode Community Forums
 


Ping from within bash?

Click here to go to the original topic
Goto page 1, 2  Next
 
       Linode.com Forum Forum Index -> General Discussion
Author Message
jti



Joined: 29 Oct 2007
Posts: 24

Posted: Fri Jan 18, 2008 5:52 am    Post subject: Ping from within bash?  

This is a general Linux question that I hope someone can help with. I have a portable drive that I use at both home & work, running a VM, and I want to be able to rsync my applications directory to backup servers at both locations. Both backup servers are on LAN's, one is a home LAN (192.168.1.2), the other uses a different address structure, and neither backup server is accessible from outside its own LAN.

I am running a bash script which issues the rsync command to both destinations, only one of which succeeds. I thought it might be possible to test which server is available via ping, and only issue the rsync command to the responding server.

Is it possible to do this in a bash script? If so how would I capture the successful ping output and use it to launch the command - in Perl I would use something like:

if ($successful_ping_to_server_a ) { rsync_server_a() }
elsif ($successful_ping_to_server_b ) { rsync_server_b() }

An alternative would be to test the VM's IP address which is different in both locations and would enable the script to determine the correct server to rsync with. But I've no idea how to do any of this in a shell script.
Back to top  
mikek



Joined: 28 Dec 2007
Posts: 2
Location: boston-ish

Posted: Fri Jan 18, 2008 7:32 am    Post subject:  

In bash, you can send a single ping:

Code: ping -c1 192.168.100.67 2>&1 > /dev/null

and then test the result via the '$?' variable. It'll be 0 if successful, non-zero if not. Something like:

Code: if [ $? == 0 ] ; then <successful ping action>
elif <failed ping action>


HTH
Back to top  
jti



Joined: 29 Oct 2007
Posts: 24

Posted: Fri Jan 18, 2008 7:54 am    Post subject:  

Yes that works a treat. Many thanks.
Back to top  
bdonlan



Joined: 22 Jan 2008
Posts: 70

Posted: Tue Jan 22, 2008 2:27 am    Post subject:  

Note that transient packet loss may cause the ping to fail - I'd have a loop to retry if both fail to respond.
Back to top  
jti



Joined: 29 Oct 2007
Posts: 24

Posted: Tue Jan 22, 2008 4:02 am    Post subject:  

OK, how's this:

for i in 1 2
ping -c1 $WORK 2>&1 > /dev/null

if [ $? == 0 ] ; then
rdiff-backup --remote-schema 'ssh -p 22 %s rdiff-backup --server' --exclude **/.svn $SOURCE $WORK::$DEST
echo 'rdiff-backup to WORK successful'
done
else ping -c1 $HOME 2>&1 > /dev/null
if [ $? == 0 ] ; then
rdiff-backup --remote-schema 'ssh -p 2995 %s rdiff-backup --server' --exclude **/.svn $SOURCE $HOME::$DEST
echo 'rdiff-backup to HOME successful'
done
fi
fi
echo 'rdiff-backup unsuccessful'
done

I have the nested statements indented but the formatting isn't reproduced here.
Back to top  
bdonlan



Joined: 22 Jan 2008
Posts: 70

Posted: Thu Jan 24, 2008 12:49 am    Post subject:  

jti wrote: OK, how's this:
Code:
for i in 1 2
  ping -c1 $WORK 2>&1 > /dev/null

  if [ $? == 0 ] ; then
     rdiff-backup --remote-schema 'ssh -p 22 %s rdiff-backup --server' --exclude **/.svn $SOURCE $WORK::$DEST
   echo 'rdiff-backup to WORK successful'
   done
else ping -c1 $HOME 2>&1 > /dev/null
   if [ $? == 0 ] ; then
      rdiff-backup --remote-schema 'ssh -p 2995 %s rdiff-backup --server' --exclude **/.svn $SOURCE $HOME::$DEST
      echo 'rdiff-backup to HOME successful'
      done
   fi
fi
echo 'rdiff-backup unsuccessful'
done

I have the nested statements indented but the formatting isn't reproduced here.
To escape a shell loop early, you must use break, not done.

Also, use code tags to indent properly :)
Back to top  
jti



Joined: 29 Oct 2007
Posts: 24

Posted: Thu Jan 24, 2008 4:11 am    Post subject:  

Quote: To escape a shell loop early, you must use break, not done.

Yes, I realised that sometime after I posted and found it didn't actually work, and went back to Google for some answers! Also needed to use 'do ping' after the 'for i in 1 2' statement. It seems to be working properly now.
Back to top  
SteveG



Joined: 30 Nov 2003
Posts: 224

Posted: Thu Jan 24, 2008 4:59 pm    Post subject:  

While there are some nice characteristics about bash (or shell scripting in general), at a certain level of complexity, switching to perl or python makes life much easier. Yes, interacting with the filesystem or other processes becomes a little more verbose (less so in perl), but you gain a level of consistency and power (again, less so in perl (yeah, I'm a python fan)) that will make your life happier and less error-prone in the long run.
Back to top  
jti



Joined: 29 Oct 2007
Posts: 24

Posted: Fri Jan 25, 2008 2:37 pm    Post subject:  

Yes I normally do things like that in Perl (never used Python), but thought it was time I learned some shell scripting. Not sure about Python being more powerful than Perl though :)
Back to top  
cz9qvh



Joined: 19 Jan 2008
Posts: 14

Posted: Fri Jan 25, 2008 3:25 pm    Post subject:  

ruby imo :P
Back to top  
jti



Joined: 29 Oct 2007
Posts: 24

Posted: Fri Jan 25, 2008 3:54 pm    Post subject:  

Well, at the risk of igniting a programming flame war and going seriously OT - I tried Ruby and soon wondered what it can do that Perl can't. It's probably a reasonble choice though for someone starting out with no 'traditional' programming skills.

I also tried Rails, and again kept having the feeling that I can do all this stuff already in Perl, and that surely Perl must have an equivalent framework to Rails - and found Catalyst and have never looked back. YMMV of course :wink:
Back to top  
SteveG



Joined: 30 Nov 2003
Posts: 224

Posted: Fri Jan 25, 2008 6:48 pm    Post subject:  

jti wrote: Not sure about Python being more powerful than Perl though :)

Well, I was partially being facetious, and partially serious. I don't think Python is "more powerful" than Perl; they're roughly equivalent levels in the programming language hierarchy (the one that begins with assembler, then C, and ends with LISP). However, having done some work with both (I'm not an expert in either), I find Python to be a lot more readable and maintainable long-term, and have reduced my Perl usage to things that are basically fancy grep/sed/awk scripts, where matching a regexp is the main functionality (which Python can do too, of course, in a more wordy way), and which I *really* don't expect to have to re-use. I also am of the opinion that Python's OO facilities are a LOT more usable/readable/comfortable than Perl's blackmagic implementation. YMMV.

Ruby, at a *very* casual glance, appears to be more-or-less equivalent to Python, with a slightly more Perl-ish flavor. Which to prefer seems to be completely a matter of taste. I came across Python first, and don't feel a particular need to learn Ruby too.
Back to top  
cz9qvh



Joined: 19 Jan 2008
Posts: 14

Posted: Sun Jan 27, 2008 11:42 am    Post subject:  

jti wrote: Well, at the risk of igniting a programming flame war i don't think there's any real risk of that here, lol. Like steve said though, it's not about which language is more powerful, they all three do the same things. Its about which is most elegant.

Hmm, consider the task of splitting a string into words and printing each on its own line. in ruby i would do:
Code: "This is a string".split(" ").each {|w| printline w}
in perl i would do something like
Code: $s = "This is a string";
while ($s =~ s/^(\w+ ?)//) {printline $1;}

Python would be similar to #1 yes? I would provide a python example but i'm sure it would suck.
Back to top  
jti



Joined: 29 Oct 2007
Posts: 24

Posted: Sun Jan 27, 2008 1:06 pm    Post subject:  

Hmm, never heard of printline in Perl, and that's a truely horrible substitution for the Perl example :(

a nicer (IMO) version of the Perl example:
Code: my $s = "This is a string";
print join ' ', split /\s+/, $s;

or:
Code: my @words = split /\s+/, "This is a string";
print join ' ', @words;

or if you want to do it on one line like the Ruby example:
Code: print join ' ', split /\s+/, "This is a string";

or (almost) same thing:
Code: print join ' ', split / /, "This is a string";

or same thing capturing the regex like the original example:
Code: print join $1, split /(\s+)/, "This is a string";

or .... etc (TIMTOWTDI - in Perl ;))

Edit: sorry, just realised your example said to print each word on its own line (though your Perl example didn't do that!!). In that case replace all Code: join ' ' in my examples with Code: join "\n"
Back to top  
cz9qvh



Joined: 19 Jan 2008
Posts: 14

Posted: Sun Jan 27, 2008 2:17 pm    Post subject:  

jti wrote: Hmm, never heard of printline in Perl, and that's a truely horrible substitution for the Perl example :(

Thanks, those are much better examples than mine :).

as to the Code: printline bit that i used, um, the implementation of printline is an exercise for the reader :wink:
Quote: (though your Perl example didn't do that!!) that just depends on the implementation of printline, i guess.



There sure are many perl ways! heh

Code: print join '\n', split / /, "This is a string"; this one stood out as my favorite. If you read it backwards its makes a lot of sense!
Back to top  
 
       Linode.com Forum Forum Index -> General Discussion Goto page 1, 2  Next
Page 1 of 2