View Full Version : Script help please!

31st October 2007, 02:15 PM
Hi there.

I'm fairly new to linux and need some help with a script i'm attempting to write to scp some data to another server i have in place. The scp works fine but what i need is for the copy to start to another system i have in place if the initial copy fails... Any help would be great cheers.

Here's the scp i have setup for the copy to the first box.

yesterday=`date --date="-1 day" +%Y%m%d`
scp -i /root/.ssh/id_maillog /var/log/syslog/maillog-$yesterday.log data@logbox1:/data/log

If the system 'logbox1' is unreachable for any reason, how can i amend my script to scp to 'logbox2'???



31st October 2007, 02:22 PM
yesterday=`date --date="-1 day" +%Y%m%d`
ping -c 3 logbox1 2>&1 >/dev/null
if [ $? -eq 0 ] ; then
scp -i /root/.ssh/id_maillog /var/log/syslog/maillog-$yesterday.log data@logbox1:/data/log
scp -i /root/.ssh/id_maillog /var/log/syslog/maillog-$yesterday.log data@logbox2:/data/log

31st October 2007, 02:23 PM
A poor fix, but could you try to ping logbox1 first and wait for a response before attempt to copy across the file and then perhaps perform some sort of md5 checksum to make sure the file arrived?

31st October 2007, 02:26 PM
Thanks, but i'm looking to automate this to run in in the early hours of the morning...

31st October 2007, 02:39 PM
That's no good. The result code for scp is in a shell variable $? so we get this

# scp foobar localhost:/tmp
foobar 100% 0 0.0KB/s 00:00
# echo $?
# scp foobar nosuchhost:/tmp
ssh: nosuchhost: Name or service not known
lost connection
# echo $?
scp follows the common convention of returning zero for success and non-zero for fail.

So a shell script could do this ...

scp foobar nosuchhost:/tmp
if [ $? -ne 0 ] ; then scp foobar localhost:/tmp ; fi

A common way to do this is to use the shell logical operators on the result value "&&" for and and "||" for or. So the code becomes

scp foobar nosuchhost:/tmp || \
scp foobar localhost:/tmp

I know the logic *seems* backwards but a bash line

cmd1 && cmd2 && cmd3 && cmd4
performs the commands in order until one fails. While

cmd1 || cmd2 || cmd3 || cmd4
continues in order till one command succeeds.

31st October 2007, 02:44 PM
#!/usr/bin/perl -w

use strict;

my ($hostname, $response, $hostname2, $yesterday)="";

$response=`ping -c3 $hostname`;
$yesterday=`date --date="-1 day" +%Y%m%d`;

print "\n$response";

if (index($response, "3 received") > -1) {
# ping was successful....
print "\nPing successful!\n";
system("scp -i /root/.ssh/id_maillog /var/log/syslog/maillog-$yesterday.log data\@$hostname:/data/log");
} else {
# ping unsuccessful, so call backup on other server
system("scp -i /root/.ssh/id_maillog /var/log/syslog/maillog-$yesterday.log data\@$hostname2:/data/log");

The above is a Perl script which you could set to run automatically via a 'cron' job that checks for a successful ping before performing the backup

31st October 2007, 02:52 PM
Nice, but pinging a target isn't really the same as testing if the scp completed successfully. Maybe the network fails an instant later, maybe the file system fills or permissions fail. Tesing the result code of scp is clearly 'the right thing'.

yesterfile=/var/log/syslog/maillog-`date --date="-1 day" +%Y%m%d`.log
scp -i /root/.ssh/id_maillog $yesterfile data@logbox1:/data/log || \
scp -i /root/.ssh/id_maillog $yesterfile data@logbox2:/data/log

31st October 2007, 03:33 PM
Thanks for all your help... I went with Bruno's example in the end. Worked a treat.


: )