Find the answer to your Linux question:
Page 1 of 2 1 2 LastLast
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... ...
  1. #1
    Just 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:
    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
    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...

    Does anyone know what I'm doing wrong ?

  2. #2
    Linux 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 so
    Code:
    BACKUP_DIR=/var/backup
    ROOT_UID=0
    E_NOTROOT=67
    STAMP=$(date +%Y%m%d)
    BACKUP_NUMBER=$(date +%k)
    HOSTNAME=$(hostname)
    Also, you shouldn't need the quotes for the date command in this case.

  3. #3
    Just Joined!
    Join Date
    May 2008
    Posts
    4
    Thanks for the fast reply BigT.

    You are partially right. I changed the script into this:
    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
    I can see that the variables are being assigned the right values.
    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 ?

  4. #4
    Linux 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

  5. #5
    Linux 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:

    Code:
    "$BACKUP_DIR"/"$STAMP"_"$BACKUP_NUMBER"_"$HOSTNAME"_websites.tar.gz
    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"

  6. #6
    Linux 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.

  7. #7
    Just 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...

  8. #8
    Linux Guru
    Join Date
    Nov 2007
    Location
    Córdoba (Spain)
    Posts
    1,513
    Quote Originally Posted by bigtomrodney View Post
    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.
    That's of course false.

    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
    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:
    $ LC_ALL=C ls -l "${VAR}"
    ls: cannot access p 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.

  9. #9
    Linux 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.

    Code:
    "${BACKUP_DIR}/${STAMP}_${BACKUP_NUMBER}_${HOSTNAME}_websites.tar.gz"
    Quote Originally Posted by i92guboj View Post
    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.
    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 boundaries

    Quote Originally Posted by i92guboj View Post
    The two mechanisms are closely related but are not quite the same.
    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.

  10. #10
    Just 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...

Page 1 of 2 1 2 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...