Ping from within bash?
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 ($successfulpingtoservera ) { rsyncservera() }
elsif ($successfulpingtoserverb ) { rsyncserverb() }
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.
19 Replies
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:
if [ $? == 0 ] ; then <successful ping="" action="">
elif <failed ping="" action=""></failed></successful>
HTH
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.
@jti:
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.
To escape a shell loop early, you must use break, not done.
Also, use code tags to indent properly :)
> 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.
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
@jti:
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.
@jti:
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:
"This is a string".split(" ").each {|w| printline w}
in perl i would do something like
$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.
a nicer (IMO) version of the Perl example:
my $s = "This is a string";
print join ' ', split /\s+/, $s;
or:
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:
print join ' ', split /\s+/, "This is a string";
or (almost) same thing:
print join ' ', split / /, "This is a string";
or same thing capturing the regex like the original example:
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
join ' '
in my examples with
join "\n"
@jti:
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
printline
bit that i used, um, the implementation of printline is an exercise for the reader
> (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
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!
my $s = "This is a string";
while ($s =~ s/^(\w+ ?)//) {printline($1);}
sub printline {
my $word = shift;
print $word, "\n"; # or, less clear but all on one line: print $_[0], "\n";
}
In that case your example would indeed have done as you suggested, and printed one word per line. The bracket - printline() - just helps make it a bit clearer and less ambiguous, and means printline doesn't need to be pre-declared.
And of course I need to point out that
> print join '\n', split / /, "This is a string";
should read
print join "\n", split / /, "This is a string";
otherwise \n is interpreted literally - This\nis\na\nstring - which I'm sure was originally a typo and you knew that already
$var =~ tr/ /\n/;
@jti:
OK, printline could be a function/method, eg:
my $s = "This is a string"; while ($s =~ s/^(\w+ ?)//) {printline($1);} sub printline { my $word = shift; print $word, "\n"; # or, less clear but all on one line: print $_[0], "\n"; }
In that case your example would indeed have done as you suggested, and printed one word per line. The bracket - printline() - just helps make it a bit clearer and less ambiguous, and means printline doesn't need to be pre-declared.
And of course I need to point out that
> print join '\n', split / /, "This is a string";
should readprint join "\n", split / /, "This is a string";
otherwise \n is interpreted literally - This\nis\na\nstring - which I'm sure was originally a typo and you knew that already
:)
EDIT oh nevermind thats the same as what you did, i just was having problems reading and thinking on that day i guess
@cz9qvh:
Python would be similar to #1 yes? I would provide a python example but i'm sure it would suck.
Just for the record the obvious way to do it in python (which is usually the best), is
s = "This is a string"
for w in s.split():
print w
$s = "This is a string";
foreach $w (split(' ', $s)) {
print "$w\n";
}
Or a bit less verbose:
$s = "This is a string";
for (split(' ', $s)) {
print "$_\n";
}