Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a short list of files and directories of which I would like to make a flat copy of using ditto in a bash shell. There are approximately 8-10 files and/or directories that need to be copied. I know that I can just create a series of conditional statements such as:

if [ -d ~/Documents ];
  ditto ~/Documents ~/BACKUP/Documents
  echo "Documents copied successfully."
  echo "WARNING: No documents were copied, directory does not exist in expected location."

However, I am curious if there is a stylistically better or more efficient way of accomplishing this task? Another approach that I have considered is creating an array that holds the files/directories and then using a loop to move through the array to copy each file. Thoughts? Ideas? Insights? Best practices?

share|improve this question
Are all the directories and files relative to your ~? Because inserting BACKUP/ into the path at the right position might be more "interesting" than it's worth. – Ulrich Schwarz Jan 24 '12 at 8:53
All of the directories and files are relative to the ~ Would you mind explaining the impact of placing a directory called BACKUP at the ~ level to copy each of these files and directories to? Thanks for the response. – Dean A. Vassallo Jan 24 '12 at 15:59
it's just that in this case, you can just do for d in Documents Movies My\ other\ files; do ditto "~/$d" "~/BACKUP/$d"; done, otherwise you need a second list for the target locations, which makes things more inconvenient. – Ulrich Schwarz Jan 24 '12 at 16:29
up vote 1 down vote accepted

You can make a loop over the directories you want to back up. Note the use of the variable err to keep track of any error.

for d in ~/Documents ~/Pictures ~/Videos; do
  if [ -d "$d" ]; then
    ditto "$d" ~/BACKUP/"${d##*/}" || err=1
    echo 1>&2 "Missing directory: $d"
exit $err

Alternatively, you can make a function that handles one directory and calls it multiple times. Note the use of err again.

backup () {
  if [ -d "$1" ]; then
    ditto "$1" "$2" || err=1
    echo 1>&2 "Missing directory: $1"
backup ~/Documents ~/BACKUPS/Documents
backup ~/Pictures ~/BACKUPS/Pictures
backup ~/Videos ~/BACKUPS/Videos
share|improve this answer
Thank you so much for the feedback. I can see how each variation has its benefits depending on the intended use. Quick question about the first example you provided, can you explain the "##*/" after the "${d"? Do you mind explaining what the hashes, asterisks, and slash translate to? Thank you. – Dean A. Vassallo Jan 25 '12 at 2:15
@DeanA.Vassallo ${VAR##PATTERN} is $VAR minus the longest prefix matching PATTERN. Here ${d##*/} is the last directory component of $d, i.e. Documents and so on. – Gilles Jan 25 '12 at 2:20

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.