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?

Toby Speight
  • 8,678
Rich Z
  • 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.... – Wildcard Mar 17 '16 at 08:51

2 Answers2

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.

Alexander
  • 9,850
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)).