Re: Help with script - doesn't work properly from cron

2009-07-20 Thread Greg Wooledge
On Fri, Jul 17, 2009 at 02:53:21PM -0700, Erik Olof Wahlstrom wrote:
 #!/bin/bash
 BACKUP_DIR=/media/disk/AUTOMATED_BACKUPS/DB_DAILY
 
 CURRENT_DIR=$BACKUP_DIR/`date +%d`

  # See how you call date here without an explicit path?  That's good.

 DATABASES=$(/usr/bin/mysql -uUsername -pPassword -Bse 'show databases')
 echo 'Backing up databases: '$DATABASES

  echo Backing up databases: $DATABASES

 if [ -e $CURRENT_DIR ]

  if [ -d $CURRENT_DIR ]

  # Of course, if it's a file, you would have problems below

 then
 cd $CURRENT_DIR
 /bin/rm *

 cd $CURRENT_DIR || exit 1
 rm -f *

 # NEVER do rm * after a cd without checking that the cd
 # succeeded!

 # You don't need an explicit path on rm.  You didn't need one
 # on date, so why put one on rm?

 # In this particular version of this particular script, you can
 # get away with not quoting the $CURRENT_DIR parameter expansion,
 # but quoting it will save your butt if someone changes it, e.g.:
 # CURRENT_DIR='/media/disk/c/Program Files'

 else
 /bin/mkdir $CURRENT_DIR

  mkdir -p $CURRENT_DIR

 cd $CURRENT_DIR

  cd $CURRENT_DIR || exit 1

 fi
 
 for DB in $DATABASES
 do
 /usr/bin/mysqldump -uroot -pHardAsMySql321 $DB | bzip2 
 $DB_`date +%Y-%m-%d_%k.%M`.sql.bz2

 # Long line, probably broken by your mailer.  For clarity, I'd
 # write it on two lines explicitily:

 mysqldump -uroot -pHardAsMySql321 $DB |
   bzip2  ${DB}_$(date +%Y-%m-%d_%k.%M).sql.bz2

 done
 
 exit 0
 
 Can any skilled eyes see why this doesn't work when it is run from the roots
 crontab?

None of the changes I suggested should really affect that.  Perhaps it's
some sort of mysql-specific thing?

 Additionally, when I run the script as root in the terminal, I get the
 following output:
 
 Backing up databases: information_schema db1 db2 db3
 /bin/rm: cannot remove `*': No such file or directory

The rm -f will suppress that error message.

 Is there a better way to clear out last months files before making the
 current backups?

You could also consider writing it this way:

  cd /
  rm -rf $CURRENT_DIR
  mkdir -p $CURRENT_DIR
  cd $CURRENT_DIR || exit 1

Then you don't even need to check whether it already exists.


On Sat, Jul 18, 2009 at 11:25:13AM +0200, Bernd Eggink wrote:
 You could replace the whole if-then-else clause by
 
 mkdir -p $CURRENT_DIR
 cd $CURRENT_DIR
 rm -f *

Another failure to check the results of cd before doing rm *.  This
can and will lead to disasters.




Re: Help with script - doesn't work properly from cron

2009-07-20 Thread Bob Proulx
Greg Wooledge wrote:
 Erik Olof Wahlstrom wrote:
  /usr/bin/mysqldump -uroot -pHardAsMySql321 $DB | bzip2 
  $DB_`date +%Y-%m-%d_%k.%M`.sql.bz2
 
  # Long line, probably broken by your mailer.  For clarity, I'd
# write it on two lines explicitily:
 
  mysqldump -uroot -pHardAsMySql321 $DB |
  bzip2  ${DB}_$(date +%Y-%m-%d_%k.%M).sql.bz2

You might want to set umask restrictive so that the backup file
created by the redirection isn't world readable.

  umask 077

I have never liked whitespace in filenames and %k may produce spaces
in filenames.  Better IMNHO to use %H here and avoid the space.  Why
use a dot instead of the more common colon in the time?

  mysqldump -uroot -pHardAsMySql321 $DB |
bzip2  ${DB}_$(date +%Y-%m-%d_%H:%M).sql.bz2

 You could also consider writing it this way:
 
   cd /
   rm -rf $CURRENT_DIR
   mkdir -p $CURRENT_DIR
   cd $CURRENT_DIR || exit 1
 
 Then you don't even need to check whether it already exists.

Why bother changing directory there at all? :-)

  mysqldump -uroot -pHardAsMySql321 $DB |
bzip2  $CURRENT_DIR/${DB}_$(date +%Y-%m-%d_%H:%M).sql.bz2

 Bernd Eggink wrote:
  You could replace the whole if-then-else clause by
  
  mkdir -p $CURRENT_DIR
  cd $CURRENT_DIR
  rm -f *
 
 Another failure to check the results of cd before doing rm *.  This
 can and will lead to disasters.

Doing 'rm *' just makes me extremely nervous even when care is taken
to ensure that it is going to work okay.  I think it is safer to avoid
it.  Let me suggest the following:

  CURRENT_DIR=$BACKUP_DIR/`date +%d`
 ...
   cd $CURRENT_DIR || exit 1
 ...
  mysqldump -uroot -pHardAsMySql321 $DB |
bzip2  ${DB}_$(date +%Y-%m-%d_%k.%M).sql.bz2

In this case the file name is going to be SOMETHING.sql.bz2.  Instead
of using 'rm *' it would make me much less nervous to qualify that
file glob with 'rm -f *.sql.bz2' at least so that if this were to escape
and be invoked elsewhere it would have limited damage potential.

  cd $CURRENT_DIR || exit 1
  rm -f *.sql.bz2

  Is there a better way to clear out last months files before making the
  current backups?

Personally I have the following line in my /etc/cron.d/local-mysql
crontab.  The 'savelog' command with -c7 will save seven days of
datestamped backups (sufficient for my case) without further code.
That could easily be -c30 to save 30 days worth.  The 'savelog'
command pretty much handles all of your issues with datestamping and
cycling files very easily.

  30 3 * * *  root  umask 077 ; mysqldump --defaults-file=/etc/mysql/debian.cnf 
--all-databases | gzip  /var/backups/mysql.dump ; savelog -q -d -l -C -c7 
/var/backups/mysql.dump

Bob




Re: Help with script - doesn't work properly from cron

2009-07-20 Thread Erik Olof Wahlstrom

Thanks everyone for your pointers - I ended up with this:

#!/bin/bash
BACKUP_DIR=/media/disk/AUTOMATED_BACKUPS/DB_DAILY

CURRENT_DIR=$BACKUP_DIR/`date +%d`

DATABASES=$(mysql -uroot -pNewSecretPw -Bse 'show databases')
echo 'Backing up databases: '$DATABASES

cd /
rm -rf $CURRENT_DIR
mkdir -p $CURRENT_DIR
cd $CURRENT_DIR || exit 1

for DB in $DATABASES
do
mysqldump -uroot -pNewSecretPw $DB | bzip2  ${DB}_$(date
+%Y-%m-%d_%H:%M).sql.bz2
done

exit 0

It worked on the first manual run - keeping my fingers crossed for tonight!
:-P


Bob Proulx wrote:
 
 Greg Wooledge wrote:
 Erik Olof Wahlstrom wrote:
  /usr/bin/mysqldump -uroot -pHardAsMySql321 $DB | bzip2 
  $DB_`date +%Y-%m-%d_%k.%M`.sql.bz2
 
  # Long line, probably broken by your mailer.  For clarity, I'd
   # write it on two lines explicitily:
 
  mysqldump -uroot -pHardAsMySql321 $DB |
 bzip2  ${DB}_$(date +%Y-%m-%d_%k.%M).sql.bz2
 
 You might want to set umask restrictive so that the backup file
 created by the redirection isn't world readable.
 
   umask 077
 
 I have never liked whitespace in filenames and %k may produce spaces
 in filenames.  Better IMNHO to use %H here and avoid the space.  Why
 use a dot instead of the more common colon in the time?
 
   mysqldump -uroot -pHardAsMySql321 $DB |
 bzip2  ${DB}_$(date +%Y-%m-%d_%H:%M).sql.bz2
 
 You could also consider writing it this way:
 
   cd /
   rm -rf $CURRENT_DIR
   mkdir -p $CURRENT_DIR
   cd $CURRENT_DIR || exit 1
 
 Then you don't even need to check whether it already exists.
 
 Why bother changing directory there at all? :-)
 
   mysqldump -uroot -pHardAsMySql321 $DB |
 bzip2  $CURRENT_DIR/${DB}_$(date +%Y-%m-%d_%H:%M).sql.bz2
 
 Bernd Eggink wrote:
  You could replace the whole if-then-else clause by
  
  mkdir -p $CURRENT_DIR
  cd $CURRENT_DIR
  rm -f *
 
 Another failure to check the results of cd before doing rm *.  This
 can and will lead to disasters.
 
 Doing 'rm *' just makes me extremely nervous even when care is taken
 to ensure that it is going to work okay.  I think it is safer to avoid
 it.  Let me suggest the following:
 
  CURRENT_DIR=$BACKUP_DIR/`date +%d`
 ...
   cd $CURRENT_DIR || exit 1
 ...
  mysqldump -uroot -pHardAsMySql321 $DB |
   bzip2  ${DB}_$(date +%Y-%m-%d_%k.%M).sql.bz2
 
 In this case the file name is going to be SOMETHING.sql.bz2.  Instead
 of using 'rm *' it would make me much less nervous to qualify that
 file glob with 'rm -f *.sql.bz2' at least so that if this were to escape
 and be invoked elsewhere it would have limited damage potential.
 
   cd $CURRENT_DIR || exit 1
   rm -f *.sql.bz2
 
  Is there a better way to clear out last months files before making the
  current backups?
 
 Personally I have the following line in my /etc/cron.d/local-mysql
 crontab.  The 'savelog' command with -c7 will save seven days of
 datestamped backups (sufficient for my case) without further code.
 That could easily be -c30 to save 30 days worth.  The 'savelog'
 command pretty much handles all of your issues with datestamping and
 cycling files very easily.
 
   30 3 * * *  root  umask 077 ; mysqldump
 --defaults-file=/etc/mysql/debian.cnf --all-databases | gzip 
 /var/backups/mysql.dump ; savelog -q -d -l -C -c7 /var/backups/mysql.dump
 
 Bob
 
 
 
 

-- 
View this message in context: 
http://www.nabble.com/Help-with-script---doesn%27t-work-properly-from-cron-tp24542164p24579084.html
Sent from the Gnu - Bash mailing list archive at Nabble.com.





Re: Help with script - doesn't work properly from cron

2009-07-18 Thread Bernd Eggink

Erik Olof Wahlstrom schrieb:

Hello - I am having a problem with a backup script that I have put together -
when I run it as root from the terminal, it works as expected (with one
caveat); however, when cron runs it, the daily backup folder is created but
no files are deposited into that folder...

Here is the script:

#!/bin/bash
BACKUP_DIR=/media/disk/AUTOMATED_BACKUPS/DB_DAILY

CURRENT_DIR=$BACKUP_DIR/`date +%d`

DATABASES=$(/usr/bin/mysql -uUsername -pPassword -Bse 'show databases')
echo 'Backing up databases: '$DATABASES

if [ -e $CURRENT_DIR ]
then
cd $CURRENT_DIR
/bin/rm *
else
/bin/mkdir $CURRENT_DIR
cd $CURRENT_DIR
fi

for DB in $DATABASES
do
/usr/bin/mysqldump -uroot -pHardAsMySql321 $DB | bzip2 
$DB_`date +%Y-%m-%d_%k.%M`.sql.bz2
done

exit 0

Can any skilled eyes see why this doesn't work when it is run from the roots
crontab?


The reason may be that crontab commands are run with /bin/sh -c 
command (Bourne shell mode). Try changing the crontab entry to 
/bin/bash command.



Additionally, when I run the script as root in the terminal, I get the
following output:

Backing up databases: information_schema db1 db2 db3
/bin/rm: cannot remove `*': No such file or directory

Is there a better way to clear out last months files before making the
current backups?


You could replace the whole if-then-else clause by

mkdir -p $CURRENT_DIR
cd $CURRENT_DIR
rm -f *

provided the options are supported on your system.

Regards,
Bernd

--
Bernd Eggink
http://sudrala.de