Shell script to sync dotfiles repository I'm doing the git dot files thing and created a script -- my first Unix shell script -- to synchronise the repo dot files with those in the user's home. It checks which dot files exist in the repo folder (except for .git) and then archives any clashes in the home directory before symlinking to the repo... I wrote this largely by experimentation and Googling. It works, but I'm just checking to see if there's anything I missed or if there are better solutions?

#!/bin/sh

# Archive existing dot files and symlink to the new ones
# Run from ~/dotfiles

# All dot files apart from .git, . and ..
dotFiles=(`ls -da .* | grep -Pxv '\.git|\.+'`)

# Existing dot files to archive
toArchive=()

cd ~

# Archive: Find clashes and tarball+gzip them
for i in ${dotFiles[*]}; do
  toArchive=(${toArchive[@]} `ls -d $i`)
done
if [ ${#toArchive[*]} != 0 ]; then
  archiveFile="dotfiles"`date +%Y%m%d`".tar.gz"
  tar czf $archiveFile ${toArchive[*]} --remove-files
fi

# Create symlinks
for i in ${dotFiles[*]}; do
  dotFileLink="dotfiles/"$i
  ln -s $dotFileLink $i
done
Consider putting the following at the beginning of every script:

set -e
set -u


The first makes your script abort as soon as the first command exits with an error. This ensures that your script doesn’t try to operate after it’s failed. The second yields an error whenever you try to access an empty variable.
I’m not sure why you’re using arrays for dotFiles and toArchives here. Using plain variables should work just as well.
Instead of `…` it’s generally advised to use $(…). This makes the expressions nestable and arguably more readable. Well …


This leaves us with:

set -e
set -u

dotFiles=$(ls -da .* | grep -Pxv '\.git|\.+')

# Existing dot files to archive
toArchive=''

cd ~

# Archive: Find clashes and tarball+gzip them
for i in $dotFiles; do
  toArchive=$toArchive $(ls -d $i)
done
if [ "$toArchive" != "" ]; then
  archiveFile="dotfiles"$(date +%Y%m%d)".tar.gz"
  tar czf $archiveFile $toArchive --remove-files
fi

# Create symlinks
for i in $dotFiles; do
  dotFileLink="dotfiles/"$i
  ln -s $dotFileLink $i
done