0

I am using this script for backuping remote files with rsync. There is issue when I try to start I get this output with errors which I don't know how to handle. Thanks for advices if there will be any.

#!/bin/bash
#VARIABLES DEFINE TO STORE COMMANDS AND VALUES.
TODAY_DATE=$(date +%Y%m%d) #Store current date
MKDIR=$(which mkdir)    #store mkdir command
RSYNC=$(which rsync)    #store rsync command
DEL=$(which rm)             #store rm command
TAR=$(which tar)             #store tar command
MAIL=$(which mail)         #store mail command
LOGFILE='/tmp/backup.log' #store path of log file & touch this file in /tmp directory

#ADD EMAIL ID IN MAILTO FOR GETTING NOTIFICATIONS IN MAIL
MAILTO='my@email.com'
BODY="nnFor more information please check $LOGFILE.nnnThanks,n$0"

#CREATE DIRECTORY TO STORE BACKUP FILES
PRODBACKDIR=$TODAY_DATE/var/production-backup/

#IF CONDITION CHECK DIRECTORY IS PRESENT OR NOT AND IF NOT PRESENT CREATE DIRECTORY WITH PROVIDED DIR STRUCTURE.
if [ ! -d "{$PRODBACKDIR}" ] && [ `$MKDIR -p "$PRODBACKDIR"` ];
then
echo -e "Directory Created for site";
fi

#if [ ! -d “{$BLOGBACKDIR}” ] && [ `$MKDIR -p “$BLOGBACKDIR”` ];
#then
#echo -e “Directory Created for Production Blog Codebase”;
#fi

#REMOVE BACKUP FILES 7 DAYS OLDER
find /var/production-backup/ -mtime +7 -exec rm -rf {} ;

#RSYNC COMMAND  TO SYNC CODE OR DATA FROM REMOTE SERVER TO LOCAL USING SSHPASS TO PASS PASSWORD OF REMOTE SERVER
sshpass -p 'password' rsync –progress -rPz -e ssh backups@remotehost:/var/www/website $PRODBACKDIR

#FOR LOOP TO CHECK BACKUP FILES AND COMPRESSED IT WITH .TAR.GZ FILE WHICH SAVES DISK SPACE ON LOCAL SYSTEM AND ALSO REMOVE NON COMPRESSED FILES.
for DOC in $PRODBACKDIR; do
echo "`date '+%Y-%m-%d'` : ${DOC} backup started";
if [ -d ${DOC} ]; then
          FILENAME=$(echo $DOC | awk -F '/' '{print $NF}');
          TARFILE="$FILENAME-$TODAY_DATE.tar.gz";
          echo "`date '+%Y-%m-%d'` : ${DOC} archiving started.";
          $TAR -cvzf $PRODBACKDIR/$TARFILE $PRODBACKDIR/$FILENAME;

#IF CONDITION CHECK ERRORS WHILE CREATING TAR.GZ AND REPORT IF TAR COMMAND FAILS.
if [ $? -eq 0 ]; then
                       echo "`date '+%Y-%m-%d'` : ${DOC} archiving done."
                       $DEL -rf $PRODBACKDIR/$FILENAME
                       echo "`date '+%Y-%m-%d'` : ${DOC} deleting of non-archive directory done."
               else
                       echo "Error while creating tar."
                       echo -e "Error while creating tar file.$BODY" | $MAIL -s 'Error : Creating tar file' $MAILTO
                       exit 1
               fi
       fi
       echo "`date '+%Y-%m-%d %H:%M:%S'` : ${DOC} backup completed"
done


#SEND THE NOTIFICATION EMAIL AFTER SUCCESSFUL COMPLETION OF BACKUP.
echo -e "Backups successfully done for Production codebase" | $MAIL -s "Completed : Backup finished." $MAILTO

Error:

find: missing argument to `-exec'
Try 'find --help' for more information.
Unexpected remote arg: backups@remotehost:/var/www/website
rsync error: syntax or usage error (code 1) at main.c(1361) [sender=3.1.2]
2018-08-02 : 20180802/var/production-backup/ backup started
2018-08-02 : 20180802/var/production-backup/ archiving started.
20180802/var/production-backup/
2018-08-02 : 20180802/var/production-backup/ archiving done.
2018-08-02 : 20180802/var/production-backup/ deleting of non-archive directory d                                                                                                                               one.
2018-08-02 06:58:59 : 20180802/var/production-backup/ backup completed
Kusalananda
  • 333,661
Delirium
  • 378
  • Note that your latest change has broken the rsync command even more since you changed -e ssh to just ssh. The ssh would be taken as the source directory now... – Kusalananda Aug 02 '18 at 07:44
  • I'm sorry, but I will roll back your edits to the code. You are correcting the code that gives rise to your errors. Do that in your code on your machine instead. Doing it here in the question renders the question and answers useless. – Kusalananda Aug 02 '18 at 08:03

1 Answers1

3

The ; at the end of the command executed by find through -exec must be quoted to protect it from the shell. The shell will otherwise see it as the end of the find command.

Change

find /var/production-backup/ -mtime +7 -exec rm -rf {} ;

to

find /var/production-backup/ -mtime +7 -exec rm -rf {} ';'

or to

find /var/production-backup/ -mtime +7 -exec rm -rf {} \;

or to just

find /var/production-backup/ -mtime +7 -delete

if your find supports it.

Note also that your find command makes no distinction between directories, files or other things under /var/production-backup. If, for example, the /var/production-backup directory itself has not been modified in more than seven days (because no files or directories were created/deleted in it), then that whole file hierarchy would be deleted.

If you intend to only delete regular files, use

find /var/production-backup/ -type f -mtime +7 -delete

Related:


Other notes about your code:

If you do

TAR=$(which tar)

and later use

$TAR ...

to create a tar archive, then you may just as well use tar directly. There is no benefit of setting TAR to the path of the tar binary with which as that would search the PATH just like using tar directly would do. The same goes for the other commands that you store in variables.

The test [ `$MKDIR -p "$PRODBACKDIR"` ] should be a test directly on the return status of mkdir. The mkdir utility does not produce output that you can test on. You also don't have to test for existence of the directory before using mkdir -p:

if mkdir -p "$PRODBACKDIR"; then
    echo 'Directory Created for site'
fi

Also note that you are using {$PRODBACKDIR} which will add { and } to the pathname of the directory. Since it's done in a useless directory test, no harm has been done (the test has always failed). You also don't need echo -e here.

You don't need {} around variable names in variable expansions. The only place you need to write ${variable} is when the expansion is part of a string where the immediately following character is a valid character in a variable name, as in "${variable}x". You do need to double quote all variable expansions though.

The --progress option to rsync is written with two dashes, not one. Also, -e ssh is as far as I know the default for rsync since a long time.

The line

FILENAME=$(echo $DOC | awk -F '/' '{print $NF}');

could be written using a standard parameter substitution as

FILENAME=${DOC##*/}

You very rarely have to test against $?. For example, instead of

tar ...
if [ $? -eq 0 ]; then ...

do

if tar ...; then ...

Also consider using printf for outputting variable data.

You're defining TODAY_DATE as a string holding today's date, but you use it only twice. There are at least three other invocations of date with a slightly different format though... (also, %Y-%m-%d could be replaced by %F, see man strftime).

You don't need ; at the end of commands that are not immediately followed by other commands on the same line. Newline works as a command terminator.

Etc., ...

I would also suggest looking into existing backup software. I could recommend borgbackup and restic for example.

Related:

Kusalananda
  • 333,661
  • Damn thank you..half of the problem solved! :-) I still fight with the error Unexpected remote arg: backups@remotehost:/var/www/website rsync error: syntax or usage error (code 1) at main.c(1361) [sender=3.1.2] – Delirium Aug 02 '18 at 07:21
  • @Delirium Updated answer. – Kusalananda Aug 02 '18 at 07:28
  • Thank you for really awesome advices. I will improve my script with your tips, this is really good. Edited my main post, just rsync. Still having troubles.. not sure what I am doing wrong with it :-/ @Kusalananda – Delirium Aug 02 '18 at 07:37