sshpassとbashのバックアップスクリプトでバグを発見

sshpassとbashのバックアップスクリプトでバグを発見

このスクリプトを使用して、rsyncを介してリモートファイルをバックアップしています。問題は起動しようとしたときに発生し、処理方法が不明なエラーが出力されます。ご提案いただきありがとうございます。

#!/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='[email protected]'
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

間違い:

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

答え1

;シェルから保護するには、実行されたコマンドの末尾を引用符で囲む必要があります。それ以外の場合、シェルはそれをコマンドの終わりとして扱います。find-execfind

変化

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

到着

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

または

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

それとも

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

あなたがfindそれをサポートしている場合。

また、コマンドはfind以下のディレクトリ、ファイル、またはその他のコンテンツを区別しません/var/production-backup。たとえば、/var/production-backupディレクトリ自体が7日以上変更されていない場合(ファイルまたはディレクトリが作成/削除されていないため)、ファイル階層全体が削除されます。

通常のファイルのみを削除するには、次を使用します。

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

関連:


コードに関する追加の注意:

そうすれば

TAR=$(which tar)

そして後で使用

$TAR ...

アーカイブを作成しtarてから直接使用することもできますtar。バイナリTARが直接使用されているかのように検索されるため、バイナリパスを設定しても利点はありません。変数に保存されている他のコマンドも同様です。tarwhichPATHtar

テストは[ `$MKDIR -p "$PRODBACKDIR"` ]戻り状態を直接テストする必要がありますmkdir。このmkdirユーティリティはテスト用の出力を生成しません。また、以下を使用する前にディレクトリが存在するかどうかをテストする必要はありませんmkdir -p

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

{$PRODBACKDIR}また、これを使用してディレクトリのパス名を追加していることに{注意してください。}役に立たないディレクトリテストで行われたため、被害はありませんでした(テストは常に失敗しました)。echo -eここでも必要ありません。

{}変数拡張では、変数名を囲む必要はありません。これを作成する必要がある唯一のケースは、拡張が${variable}文字列の一部であり、拡張の直後の文字が以下のように変数名の有効な文字である場合です"${variable}x"。あなたするただし、すべての変数には拡張に二重引用符が必要です。

オプションは1つではなく2つのダッシュで作成されます--progressrsyncまた、-e ssh私が知っている限り、これはrsync長い間デフォルトです。

ライン

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

これは、標準パラメータ置換を使用して次のように書くことができます。

FILENAME=${DOC##*/}

$?たとえば、代わりに。

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

する

if tar ...; then ...

また、printf変数データの出力に使用することも検討してください。

TODAY_DATE今日の日付を保存する文字列を定義しましたが、2回だけ使用しました。ただし、書式がわずかに異なる呼び出しが少なくとも3つありますdate。 (%Y-%m-%d交換可能%F、参照man strftime

;同じ行の他のコマンドが直後にないコマンドの最後に追加する必要はありません。改行文字はコマンドターミネーターとして使用されます。

など。 、...

また、既存のバックアップソフトウェアを調べることをお勧めします。たとえば、borgbackupお勧めできますrestic

関連:

関連情報