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?

  • 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. Commented Jan 24, 2012 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.
    – sardean
    Commented Jan 24, 2012 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. Commented Jan 24, 2012 at 16:29

1 Answer 1


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
  • 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.
    – sardean
    Commented Jan 25, 2012 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. Commented Jan 25, 2012 at 2:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .