Use ditto to Copy Files & Directories Intelligently from the Mac Terminal
Most longtime command line users rely on the cp command to copy files and directories, but Mac OS X offers another solution with the ‘ditto’ command. Ditto is slightly more advanced but can be advantageous to ‘cp’ for several reasons, as it not only preserves ownership attributes and permissions but also file resource forks and file and folder metadata, essentially insuring that the file and/or folders are copied exactly.
Additionally, ditto can be used to copy a file or folder to a source directory, but if that source doesn’t yet exist, ditto will automatically create it. Also, if the destination folder does exist, the copied contents will be merged together in that destination directory. Finally, ditto also follows symbolic links, making it particularly handy if you’re a heavy user of the ln command.
To better understand the ditto command, let’s run through a few examples with real syntax.
Using Ditto to Copy Files / Folders
At it’s most simple form, ditto works much like the cp command, with basic syntax as follows:
ditto source destination
For example, if you wanted to copy ~/Desktop/FluffyBackups to /Volumes/FluffyBackups/ you would just type the following:
ditto ~/Desktop/FluffyBackups /Volumes/FluffyBackups/
Again, this will retain all ownership and resource metadata details of the files copied, which may be particularly important if you’re copying files from one user directory to another, or if you want to preserve something like modification times of files.
If you’re uncertain about the source and destination contents, you can always compare the two with the comm command or the diff command before proceeding with the ditto command.
Using Ditto to Merge Directories & Folder Contents
Remember, ditto will check to see if the destination already exists, and if it does, it will merge the directories of the source to the destination. This is important and extremely useful, making it one of the easiest ways to merge the directories from the command line in Mac OS X (though it’s easy now in the Finder too).
ditto ~/Pictures/Fall2015/ /Volumes/PhotoBackup/2015/
This would take all pictures from “Fall2015” and copy them into the pre-existing directory “2015”, effectively merging the contents from the source to the destination. Again, the merge behavior occurs when the destination already exists, if the destination doesn’t exist it would be created as specified, or as the source name.
If you’re using ditto to copy data from directories with symbolic links, using the -V (verbose all) flag is valuable because it will display every file and symbolic link that has been copied. Note -V is different than -v, which will only show files as output, and not symbolic links.
Copy Without Metadata Using Ditto
If for some reason you don’t want to copy metadata and resource forks, youc an use the –norsrc flag like so:
ditto -V --norsrc ~/Sample/Folder /Volumes/NoMetadataBackups
Using the –norsrc flag kind of defeats a primary benefit of ditto, but it can be useful for some cases.
You can learn much more about the excellent ditto command by reading its manual page, accessible in Mac OS X by typing:
man ditto
As usual, use the arrow keys to navigate up and down in the manual page.
Before you rely on ditto heavily, be sure to try it out a few times with inconsequential file moves and directory merges to understand how it works with your planned usage.
Thanks for this. When I attempt a ‘ditto’ from single user mode in MacOS 10.12.6 to an NTFS external drive I get a read-only error. Any suggestions?
I disabled csrutil in single-user recovery mode first.
Then rebooted to single user mode.
Then fsck -fy, then mount -uw /
Then mkdir /volumes/usb
Then mount -t ntfs -w -v /dev/disk2s1 /volumes/usb
Then mount -uw /volumes/usb
Returned “unknown special file system”
Tried ditto -V /users /volumes/usb/KristinMac/users
Returned “read-only file system”
Any ideas?
Thanks!
I am using the ditto command to copy folders & files content from networked share to local external media (USB drive) within Mac OS X environment… content appears to copy OK, but some folders & files copy with “attribute not found” errors (any ideas on how to fix these copying issues)? Should I try the comm… diff… cp commands?
ditto /Volumes/CS/Service\ Desk/Desktop/OSX/UpdateOSXbootMedia/TUCS-MacOSX “/Volumes/TUCS-MacOSXbootMedia/TUCS-MacOSX”
You can use Long Path Tool for this problem.
Can ditto be used to copy a file form a windows share to a local folder by calling out a smb//:xxx.xxx.xxx.xxx as the source? If not what is the best way to do this form the terminal?
Thanks, good to know!
Merge seems to be a misnomer. According to man, “ditto
overwrites existing files, symbolic links, and devices in the destination when these are copied from a source.” I tend to think of Merge as keep existing, add missing files. So if destination has a newer version of the same file name, ditto would apparently replace the newer version with the older one.
This is great, but what about using a command that checks if an item exists, and if it does, if it is not newer then do not copy over. That is more “Intelligent”
rsync
Slightly off-topic: for easy man page reading, install Bwana (http://www.bruji.com/bwana/). It allows you to type, e.g., man:ditto in the address bar of a browser, and the man page will open in your browser. Much easier than in the terminal.
I’m sure your recommendation to use ditto instead of cp is a good one, but cp has preserved resource forks for over a decade. I remember Apple first offered a version of cp that ignored resource forks, then offered a version called cp_mac that handled resource forks. It was a long time ago, but it may have been around 10.1. By 10.2 or 3, the regular cp copied resource forks with no problem.
Ditto does that too, the man page tells: “ditto will preserve resource forks and HFS meta-data information when copying unless instructed otherwise using –norsrc .”
Very good stuff. I’ve found that ditto works great when moving data from a Windows server onto a Mac. It seems to be a lot less error prone.