0

I am trying to create a routine to manage the backup files I am creating, so that older folders will be deleted automatically in the process. Here’s what I've got:

#!/bin/sh
day=$(date +%m%d%y)
oldday=$(date -d "-4 days" +%m%d%y)
mkdir /home/fauna/backup/$day
rm -r /home/fauna/backup/$oldday
cp /home/fauna/backup/backup.sh /home/fauna/backup/$day
cd /home/fauna/backup/$day
./backup.sh

backup.sh actually does the creation of the backup files and then copies the folder with those files to a remote location.

Will that rm line delete that old folder without any unintended consequences?

Can I move it to after the backup.sh line?

1
  • 1
    You may want to create the new backup file before you delete the old one. You know, so that you have a backup.... Commented Mar 17, 2016 at 8:51

2 Answers 2

3

Adding a check is a good idea:

if [[ -d ~/backup/$oldday ]]; then
  rm -rf "$HOME/backup/$oldday"
fi

Also, using single or double quotes correctly in bash is important. Especially directory names with spaces in them can cause problems when not using quoting.

Update: I am assuming OP wants to use bash.

4
  • Doesn't the comment about quotes also apply to the part that comes between the [[ and ]]? Commented Mar 17, 2016 at 8:47
  • 1
    @RealSkeptic, no, it doesn't. Commented Mar 17, 2016 at 8:49
  • The OP never mentioned bash. [[...]] is ksh syntax (also supported by zsh and bash), not sh. Commented Mar 17, 2016 at 9:11
  • 1
    @Wildcard It doesn't in this case, but you might want to get into the habit of using double quotes anyway, because in [[ $a == $b ]] the lack of double quotes around $b does make a difference. I added a note to this effect in that answer. Commented Mar 17, 2016 at 22:39
2

You've got a few issues with coding practice in your code.

  1. You'd want to check for the success of those commands especially when the next command depends on the success of the previous one.
  2. Leaving a variable unquoted in list context is asking the shell to split it and perform filename generation on it, there's no reason you'd want to do that here.

Now about rm -r, it's mean to delete the directory and all its content. It will not follow symlinks when doing so. Even if /home/fauna/backup/$oldday is a symlink, only that symlink is removed. That's probably what you want here. It would be different if you did rm -r "/home/fauna/backup/$oldday/" (with the trailing /).

However, without -f, that that means that if stdin is a terminal, you could be prompted for the removal of non-writable files. So, if it's meant to be an unattended script, you should probably add it. Also with -f, rm only reports failure if the directory if still there afterwards.

#!/bin/sh -
day=$(date +%m%d%y) || exit
oldday=$(date -d "-4 days" +%m%d%y) || exit
# date is very unlikely to fail, but if it does, it would have dramatic consequences

# shouldn't access to those directories be restricted (if it hasn't been
# restricted already some levels above)?
# umask 077

mkdir -p "/home/fauna/backup/$day" || exit
# with -p, mkdir would only fail if the directory is not there after that call.
# It may not be what you want though. You may want mkdir to fail if the
# directory already existed in which case you'd want to omit the -p.

cp /home/fauna/backup/backup.sh "/home/fauna/backup/$day" || exit

cd "/home/fauna/backup/$day" || exit
./backup.sh || exit

# only delete the old one if the new one succeeds.
rm -rf "/home/fauna/backup/$oldday"

Note that here since we're adding || exit to every command, we might as well use set -e which causes the shell to exit upon any error of any command, but I prefer || exit as it makes it explicit that you've given consideration into error handling (and set -e has too many gotchas to be used reliably (not in this simple case here though)).

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.