1

This isn't a particularly hard question but I'm starting out in Bash and a few things are tripping me up. I'm trying to automate some backups to AWS S3 but also add a bit of logic to it. I want to code to look like this:

  1. Make sure the user has passed what $FOLDER they want to copy when calling the script, if not, warn and exit i.e sh backup.sh logfolder
  2. Check if the bucket exists, the bucket name being the $HOSTNAME of the server
  3. If the bucket doesn't exist, warn and create, else move on
  4. Move the files from the local $FOLDER to the S3 bucket and $FOLDER specified

A simple way to to always run the command aws s3 mb s3://$HOSTNAME but this seams wasteful as under almost every circumstance it will exist so running something like aws s3 ls s3://$HOSTNAME and if the output contains NoSuchBucket then create the bucket, else (the bucket is there) then move on to the move command.

I have seen I could use 2> &1 and then call this with the variable name $1, however I am already using $1 to pass the folder name at the start. The other issue I had was how to run the command, then check the output. Would I create a variable which is the command? Or just run the command and put the output in to a variable, then search the output? I.e something 1 or 2

1) BUCKETCHECK=$(aws s3 mb s3://$HOSTNAME/) 2> &1

if $1 = NoSuchBucket then create bucket, else copy files

2) aws s3 ls s3://$HOSTNAME/ 2> &1

if $1 = NoSuchBucket then create bucket, else copy files

Or maybe neither of the two are correct?

The Script:

REGION="eu-west-1"
FOLDER=$1

# Debug Code
DEBUG=0
if [ ${DEBUG} = 1 ]
then
   echo ${HOSTNAME}
   echo ${FOLDER}
   echo ${REGION}
fi

# Get function from functions library
#. /etc/init.d/functions

if [ ${FOLDER} = 0 ]
then
    echo "Please input a folder name"
    exit 1
BUCKETCHECK=$(aws s3 ls s3://$HOSTNAME/ 2>&1)
elif [ ${BUCKETCHECK} = "An error occurred (NoSuchBucket) when calling the ListObjects operation: The specified bucket does not exist" ]
then
  echo "Creating Bucket"
  aws s3 mb s3://${HOSTNAME}/
#elif [ ${FOLDERCHECK} = 0 ]
#then
#    echo "Folder does not exist, will create it"
#    aws s3 cp ${FOLDER} s3://${HOSTNAME}/${FOLDER}/
else
    echo "Bucket does exist, moving files"
    aws s3 mv ${FOLDER} s3://$HOSTNAME/${FOLDER}/ --recursive --region ${REGION}
fi
CodeChris
  • 13
  • 3

1 Answers1

0

I'm not exactly sure, but you seem to confuse &1 and $1. The expression '2>&1' means that the output that would normally go to stderr is redirected to stdout (see In the shell, what does " 2>&1 " mean?).

Imho this should work:

BUCKETCHECK=$(aws s3 mb s3://$HOSTNAME/ 2>&1)
if [ "$BUCKETCHECK" = "NoSuchBucket" ]; then
  echo create bucket;
fi
Community
  • 1
  • 1
ivanhoe
  • 99
  • 1
  • 5
  • Thanks for the tip, I think you are right about my confusion. The command you sent still doesn't work, but I think it's giving me the push in the right direction. Thanks – CodeChris Feb 20 '17 at 13:53
  • Ok then maybe the command is putting out more than just "NoSuchBucket". Perhaps you can provide your script and what output you're getting for further assistance. – ivanhoe Feb 21 '17 at 08:11
  • It is, but I have added the whole text string that is output. I'll post the script, and then the error that happens; This gives these errors, they correspond to the IF on the first folder and the first ELIF s3backup.sh: line 30: [: =: unary operator expected s3backup.sh: line 35: [: =: unary operator expected If then goes to else and echos "Bucket does exist", but it doesn't as I've checked, so it's not liking the butcket check section so just going to else, I presume – CodeChris Feb 21 '17 at 08:51
  • I recommend having a look at the [man page for test](https://linux.die.net/man/1/test), which explains the expressions you can use inside the brackets of conditionals. In particular, if you want to check for an empty string use -z (if [ -z $FOLDER ]; then ...) and '=' expects strings, so you need to put ${BUCKETCHECK} in double quotes on line 35. – ivanhoe Feb 21 '17 at 10:14