Results 1 to 10 of 11
Hi all,
I'm trying to write my first shell script and I've ran into a problem which I can't seem to solve so I thought I'd try my luck here...
...
- 05-11-2008 #1Just Joined!
- Join Date
- May 2008
- Posts
- 4
Backup script not working
Hi all,
I'm trying to write my first shell script and I've ran into a problem which I can't seem to solve so I thought I'd try my luck here...
I think it's not that hard, but I'm pretty clueless atm so I hope someone can help me.
The code:
When I run this code in Debian I can see that the file name gets cut off after $BACKUP_DIR/ so I think I need to escape the / but I've tried all kinds of variations with double and single quotes but to no avail...Code:#!/bin/sh -x ################################################################# # Author : Michel van Son # # Company : Phison Technologies # # Date : 11-05-2008 # # Purpose : Prepare system for backup by dumping databases and copy websites # # Changes: [DD-MM-YYYY] Name - company : changes # ################################################################# BACKUP_DIR=/var/backup ROOT_UID=0 E_NOTROOT=67 STAMP= date "+%Y%m%d" BACKUP_NUMBER= date "+%k" HOSTNAME=hostname # Check if user is root if [ "$UID" != "$ROOT_UID" ]; then echo "Must be root to run this script." exit $E_NOTROOT fi # Check if /var/backup exists if [ -e "$BACKUP_DIR" ]; then echo "Found: $BACKUP_DIR" else echo "$BACKUP_DIR does not exist, so I'll create it for you." mkdir /var/backup fi # Dump all databases mysqldump -uroot -ppassword --all-databases> "$BACKUP_DIR/$STAMP_$BACKUP_NUMBER_$HOSTNAME_mysqlbackup.sql" # Create website archive tar -czf "$BACKUP_DIR/$STAMP_$BACKUPNUMBER_$HOSTNAME_websites.tar.gz" /var/www # Remove old backups BACKUP_NUMBER=$BACKUP_NUMBER-1 if [ -e $BACKUP_DIR/$STAMP_$BACKUPNUMBER_$HOSTNAME_mysqlbackup.sql ]; then rm $BACKUP_DIR/$STAMP_$BACKUPNUMBER_$HOSTNAME_mysqlbackup.sql else echo "No previous SQL backup present. Please verify." fi if [ -e $BACKUP_DIR/$STAMP_$BACKUPNUMBER_$HOSTNAME_websites.tar.gz ]; then rm "$BACKUP_DIR/$STAMP_$BACKUPNUMBER_$HOSTNAME_websites.tar.gz" else echo "No previous web backup present. Please verify." fi
Does anyone know what I'm doing wrong ?
- 05-11-2008 #2Linux Guru
- Join Date
- Nov 2004
- Posts
- 6,110
It looks like the problem is in your variable setting. If you want $STAMP etc. to be populated you need to have the commands evaluated, otherwise they will be treated as literal strings.
Change your variable section like soAlso, you shouldn't need the quotes for the date command in this case.Code:BACKUP_DIR=/var/backup ROOT_UID=0 E_NOTROOT=67 STAMP=$(date +%Y%m%d) BACKUP_NUMBER=$(date +%k) HOSTNAME=$(hostname)
- 05-11-2008 #3Just Joined!
- Join Date
- May 2008
- Posts
- 4
Thanks for the fast reply BigT.
You are partially right. I changed the script into this:
I can see that the variables are being assigned the right values.Code:#!/bin/sh -x ################################################################# # Author : Michel van Son # # Company : Phison Technologies # # Date : 11-05-2008 # # Purpose : Prepare system for backup by dumping databases and copy websites # # Changes: [DD-MM-YYYY] Name - company : changes # ################################################################# BACKUP_DIR=/var/backup ROOT_UID=0 E_NOTROOT=67 STAMP=$(date +%Y%m%d) BACKUP_NUMBER=$(date +%k) HOSTNAME=$(hostname) # Check if user is root if [ "$UID" != "$ROOT_UID" ]; then echo "Must be root to run this script." exit $E_NOTROOT fi # Check if /var/backup exists if [ -e "$BACKUP_DIR" ]; then echo "Found: $BACKUP_DIR" else echo "$BACKUP_DIR does not exist, so I'll create it for you." mkdir $BACKUP_DIR fi # Dump all databases mysqldump -uroot -ppassword --all-databases> $BACKUP_DIR/$STAMP_$BACKUP_NUMBER_$HOSTNAME_mysqlbackup.sql # Create website archive tar -czf $BACKUP_DIR/$STAMP_$BACKUPNUMBER_$HOSTNAME_websites.tar.gz /var/www # Remove old backups BACKUP_NUMBER=$BACKUP_NUMBER-1 if [ -e $BACKUP_DIR/$STAMP_$BACKUPNUMBER_$HOSTNAME_mysqlbackup.sql ]; then rm $BACKUP_DIR/$STAMP_$BACKUPNUMBER_$HOSTNAME_mysqlbackup.sql else echo "No previous SQL backup present. Please verify." fi if [ -e $BACKUP_DIR/$STAMP_$BACKUPNUMBER_$HOSTNAME_websites.tar.gz ]; then rm $BACKUP_DIR/$STAMP_$BACKUPNUMBER_$HOSTNAME_websites.tar.gz else echo "No previous web backup present. Please verify." fi exit
This is the output:
+ BACKUP_DIR=/var/backup
+ ROOT_UID=0
+ E_NOTROOT=67
++ date +%Y%m%d
+ STAMP=20080511
++ date +%k
+ BACKUP_NUMBER=23
++ hostname
+ HOSTNAME=psnnl01s005
+ '[' 0 '!=' 0 ']'
+ '[' -e /var/backup ']'
+ echo 'Found: /var/backup'
Found: /var/backup
+ mysqldump -uroot '-ppassword' --all-databases
+ tar -czf /var/backup/.tar.gz /var/www
tar: Removing leading `/' from member names
+ BACKUP_NUMBER=23-1
+ '[' -e /var/backup/.sql ']'
+ rm /var/backup/.sql
+ '[' -e /var/backup/.tar.gz ']'
+ rm /var/backup/.tar.gz
+ exit
I also tried escaping the filename string but that doesn't seem to make a difference...What is going wrong ?
- 05-11-2008 #4Linux Guru
- Join Date
- Nov 2004
- Posts
- 6,110
Right I found a couple of things. First thing is that the underscores don't act as delimiters, so it helps to quote the variables when concatenating them together so they are parsed correctly. The second thing is you missed a few underscores too in your variable names ($BACKUP_NUMBEr vs. $BACKUPNUMBER). I'm posting the debug script I used as is because I'm off to bed now. Also, I commented out the root check as I ran it as a normal user...
Code:#!/bin/sh -x #Author : Michel van Son # # Company : Phison Technologies # # Date : 11-05-2008 # # Purpose : Prepare system for backup by dumping databases and copy websites # # Changes: [DD-MM-YYYY] Name - company : changes # ################################################################# export BACKUP_DIR=/home/bigtomrodney/testbackup export ROOT_UID=0 export E_NOTROOT=67 export STAMP=$(date +%Y%m%d) export BACKUP_NUMBER=$(date +%k) export HOSTNAME=$(hostname) echo BACKUP_DIR $BACKUP_DIR echo ROOT_UID $ROOT_UID echo E_NOROOT $E_NOTROOT echo STAMP $STAMP echo BACKUP_NUMBER $BACKUP_NUMBER echo HOSTNAME $HOSTNAME echo 1 String set as :- $BACKUP_DIR/"$STAMP"_"$BACKUP_NUMBER"_"$HOSTNAME"_websites.tar.gz # Check if user is root #if [ "$UID" != "$ROOT_UID" ]; then # echo "Must be root to run this script." # exit $E_NOTROOT #fi # Check if /var/backup exists echo Check if /var/backup exists if [ -e "$BACKUP_DIR" ]; then echo "Found: $BACKUP_DIR" else echo "$BACKUP_DIR does not exist, so I'll create it for you." mkdir $BACKUP_DIR fi # Dump all databases echo Dump all databases mysqldump -uroot -ppassword --all-databases> "$BACKUP_DIR"/"$STAMP"_"$BACKUP_NUMBER"_"$HOSTNAME"_mysqlbackup.sql # Create website archive echo Create website archive echo 2 String set as :- "$BACKUP_DIR"/"$STAMP"_"$BACKUP_NUMBER"_"$HOSTNAME"_websites.tar.gz tar -czf "$BACKUP_DIR"/"$STAMP"_"$BACKUP_NUMBER"_"$HOSTNAME"_websites.tar.gz /home/bigtomrodney/Support # Remove old backups echo Remove old backups BACKUP_NUMBER=$BACKUP_NUMBER-1 if [ -e "$BACKUP_DIR"/"$STAMP"_"$BACKUP_NUMBER"_"$HOSTNAME"_mysqlbackup.sql ]; then rm "$BACKUP_DIR"/"$STAMP"_"$BACKUP_NUMBER"_"$HOSTNAME"_mysqlbackup.sql else echo "No previous SQL backup present. Please verify." fi if [ -e "$BACKUP_DIR"/"$STAMP"_"$BACKUP_NUMBER"_"$HOSTNAME"_websites.tar.gz ]; then rm "$BACKUP_DIR"/"$STAMP"_"$BACKUP_NUMBER"_"$HOSTNAME"_websites.tar.gz else echo "No previous web backup present. Please verify." fi exit
- 05-12-2008 #5Linux Guru
- Join Date
- Nov 2007
- Location
- Córdoba (Spain)
- Posts
- 1,513
I haven't looked too deep into that script so I don't really know which is the problem. However, I just wanted to drop a quick note:
You can just quote the whole lot, there's no need to go quoting every single variable.Code:"$BACKUP_DIR"/"$STAMP"_"$BACKUP_NUMBER"_"$HOSTNAME"_websites.tar.gz
However, this will fail as well because there's another problem: you are not delimiting the variables the right way. To avoid such problem, you use curly brackets this way:Code:"$BACKUP_DIR/$STAMP_$BACKUP_NUMBER_$HOSTNAME_websites.tar.gz"
Code:"${BACKUP_DIR}/${STAMP}_${BACKUP_NUMBER}_${HOSTNAME}_websites.tar.gz"
- 05-12-2008 #6Linux Guru
- Join Date
- Nov 2004
- Posts
- 6,110
The idea of using the quotes was simply to delimit the variables. Given the nature of the variables and strings, if you use brackets for delimiting you shouldn't require quotes at all.
Last edited by bigtomrodney; 05-12-2008 at 11:09 AM.
- 05-12-2008 #7Just Joined!
- Join Date
- May 2008
- Posts
- 4
Thanks for the help.
The curly brackets did the trick. Now I'm struggling with the substraction.
I'm getting a "command not found" when I try to substract 2 from the $BACKUP_NUMBER.
Thanks for all the help...It was a bit harder then I thought...
- 05-12-2008 #8Linux Guru
- Join Date
- Nov 2007
- Location
- Córdoba (Spain)
- Posts
- 1,513
That's of course false.
You can see how the ls will treat ${VAR} as a list with two arguments. In the contrary, if you quote as you must, then you get only one:Code:$ VAR="p p" $ LC_ALL=C ls -l ${VAR} ls: cannot access p: No such file or directory ls: cannot access p: No such file or directory
The brackets are only a way to guarantee that the variable name doesn't get mixed with any stuff around it, but it doesn't delimit strings. The two mechanisms are closely related but are not quite the same.Code:$ LC_ALL=C ls -l "${VAR}" ls: cannot access p p: No such file or directory
- 05-12-2008 #9Linux Guru
- Join Date
- Nov 2004
- Posts
- 6,110
I think you misunderstood the context of what I was saying. I am not talkling general usage but in the particular case above. There is no whitespace in any of the variables in that script which is why I said "Given the nature of the variables and strings...". In that case you do not require strings around the longer filepath/filename string as you are delimiting the data using brackets already.
That is exactly what it is doing, it is setting the boundaries within the overall string that define what is a variable and what is not. That is exactly what delimiting is, establishing limits or boundariesCode:"${BACKUP_DIR}/${STAMP}_${BACKUP_NUMBER}_${HOSTNAME}_websites.tar.gz"
I agree completely, and the example of the code I gave was for the case in question, not a general HOWTO for variables. I found it to be suitable as there was no whitespace, and overall there is no difference in character count between the two methods. I would certainly agree that your bracket method would be the preferred method for general usage.
- 05-12-2008 #10Just Joined!
- Join Date
- May 2008
- Posts
- 4
Thanks for clearing that up...Does anyone know how I can substract 2 from the variable $BACKUP_NUMBER?
just $SOMETHING = $BACKUP_NUMBER - 2 doesn't seem to work...


Reply With Quote
