Last friday I decided to automate my Jekyll blog deployment. I wanted to create a script that would build the site, commit the changes and push them to the remote repository. I was in a hurry and I didn’t want to spend too much time on it. I just wanted to get it done. So I wrote a bash script for this purpose.

Unfortunately, the script had a small bug that I didn’t notice.

I was using the rm command to delete the ../site/*’ folder using the following command:

rm -rf ../site/*

Later I added a an argument to the script to specify the path to the site folder and changed the command to:

rm -rf $2/*

The $1 argument is the command to run (build, serve, clean, deploy) and the $2 argument is the path to the site folder. So the syntax of the script is:

./deploy.sh [command] [path]

The thing that I didn’t notice is that if I forget to specify the path argument, the script will delete file as if I had run the following command:

rm -rf /*

As you can imagine, this is a very dangerous command. It will delete all the files in the root folder. And guess what? I did it. I ran the script without specifying the path argument and it deleted all the files in the root folder!!

I than spent two days dealing with the btrfs restore and btrfs-find-roots command to try to save my home folder.

I was lucky that I use cloud storage and I had a recent backup of my home folder. I was able to restore it and recover my files.

I learned a lot from this experience. I will never forget to test the existence of the arguments of a script and set default values if an argument is missing. I will also never forget to use the --dry-run option of the rm command.

For my case I used the following commands for my script:

if [ -z "$2" ]; then
  echo "No path specified. Using default path: ../site"
  path="../site"
else
  path=$2
fi
...
echo "The following files will be deleted in $path:"
rm -rf --dry-run $path/*
read -p "Continue with file deletion? (y/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]
then
  rm -rf $path/*
else
  echo "Aborting..."
  exit 1
fi

I hope this will help you avoid making the same mistake as me.

Comments