0

OK, so I am a total beginner with bash scripts and I am aware that the question is probably phrased a bit awkwardly, but I'll be as clear as I can!

I have written the following script to create a backup of repositories in a folder. The script is as follows:

#!/bin/bash

SVNREPO="/var/svn"
TEMP="/var/tmp"
BACKUP="/home/helix/backups"

cd $SVNREPO

if [ $# -eq 0 ]; then
    for REPO in *; do
        ARRAY+=($REPO)
    done
else
    for REPO in $@; do
        ARRAY+=($REPO)
    done
fi

for REPO in ${ARRAY[@]}; do
    svnadmin dump $SVNREPO/$REPO -r HEAD | gzip > $TEMP/$REPO.svn.gzip sd
    cp $TEMP/$REPO.svn.gzip $BACKUP/$REPO.svn.gzip
    rm $TEMP/$REPO.svn.gzip 
done

This script successfully produces .gzip backups of the all of the repositories in 'var/svn' when the script is called with no arguments, and creates .gzip backups of the specific repositories that are called as arguments. Great!

However, if the script is run with an argument that does not correspond to a repository that exists, then the program will crash with the error message: svnadmin: E000002: Can't open file '/var/svn/ada/format': No such file or directory. What I am trying to achieve is to catch this error and print a more user friendly output to the console. I have been trying to do this using 'trap'.

First I added the following line:

trap 'echo ERROR! The repository or repositories that you are trying to backup do not exist!' ERR

...and then I pushed the error to /dev/null at this point in the final for loop:

svnadmin dump $SVNREPO/$REPO -r HEAD 2>/dev/null | gzip > $TEMP/$REPO.svn.gzip

I pushed to the /dev/null file at the place I did because this is where the program errors out. However, the script no longer seems to work. What am I doing wrong here? Is it an issue to do with having the 2>/dev/null in the middle of a line? If so, how could I refactor this code so that it doesn't require the pipe in the middle of the line?

Many thanks for any help, I hope my question is reasonably clear! To confirm, the final non-working code is as follows:

#!/bin/bash

SVNREPO="/var/svn"
TEMP="/var/tmp"
BACKUP="/home/helix/backups"

cd $SVNREPO

if [ $# -eq 0 ]; then
    for REPO in *; do
        ARRAY+=($REPO)
    done
else
    for REPO in $@; do
        ARRAY+=($REPO)
    done
fi

trap 'echo ERROR! The repository or repositories that you are trying to backup do not exist!' ERR

for REPO in ${ARRAY[@]}; do
    svnadmin dump $SVNREPO/$REPO -r HEAD 2>/dev/null | gzip > $TEMP/$REPO.svn.gzip sd
    cp $TEMP/$REPO.svn.gzip $BACKUP/$REPO.svn.gzip
    rm $TEMP/$REPO.svn.gzip 
done
Jens
  • 69,818
  • 15
  • 125
  • 179
jamessct
  • 821
  • 3
  • 10
  • 15
  • 1
    You can test to see if a directory exists with `if [ -d directory-name ]` or to test f a file exits use `-f` instead. – cdarke Feb 21 '17 at 16:51
  • 1
    Double quote expansions and variables, it will solve most of the problems in `bash`, `for REPO in "$@"` and `for REPO in "${ARRAY[@]}"` – Inian Feb 21 '17 at 16:52
  • 1
    @cdarke Cheers, I could probably incorporate that into my script to get it to work. – jamessct Feb 21 '17 at 16:55

2 Answers2

1

I do not know exactly how trap command works, but I will suggest another way that might solve your problem in another way:

First, before your for loop, add this line:

set -o pipefail

This means that when any command in a pipe fails, the last exit code ($?) will contain the error code if any failed.

On the line right after your svnadmin call, I would suggest adding this:

if [ $? -ne 0 ]; then
    echo "ERROR! Received error code $? for repository '$REPO'."
    continue
fi

You can of course alter the error message to your taste. The functionality should be clear: If svnadmin or bzip fails, it will print an error message and continue to next item in the for loop.

Hope this helps.

anaotha
  • 552
  • 6
  • 15
  • I tried this and it gives an error irrespective of whether there are correct, incorrect or no arguments. – jamessct Feb 21 '17 at 17:11
1

Using @cdarke suggestion of checking whether a file exists, I now have it working with the following code:

#!/bin/bash

SVNREPO="/var/svn"
TEMP="/var/tmp"
BACKUP="/home/helix/backups"

cd $SVNREPO

if [ $# -eq 0 ]; then
    for REPO in *; do
        ARRAY+=($REPO)
    done
else
    for REPO in $@; do
        ARRAY+=($REPO)
    done
fi

for REPO in ${ARRAY[@]}; do
    if [ -f $SVNREPO/$REPO/format ]; then
        vnadmin dump $SVNREPO/$REPO -r HEAD 2>/dev/null | gzip > $TEMP/$REPO.svn.gzip
        cp $TEMP/$REPO.svn.gzip $BACKUP/$REPO.svn.gzip
        rm $TEMP/$REPO.svn.gzip 
    else
        echo ERROR! The repository $REPO does not exist. No backup has been made for this argument.
    fi
done
jamessct
  • 821
  • 3
  • 10
  • 15
  • If you have found an answer to your question you should accept the answer (even your own answer) by clicking the check mark next to the answer. – I0_ol Feb 21 '17 at 19:27