Install Unison – File-Synchronization Tool for CentOS 7

Unison is self described as “a file-synchronization tool for [Linux]. It allows two replicas of a collection of files and directories to be stored on different hosts (or different disks on the same host), modified separately, and then brought up to date by propagating the changes in each replica to the other.”

Unison has no available RPM for CentOS 7, however, it can be compiled.  This installation process works for CentOS 6 as well.

yum install -y ocaml ocaml-camlp4-devel ctags ctags-etags
mkdir -p /opt/unison
cd /opt/unison
curl -O
tar xzvf unison-2.48.3.tar.gz
cd unison-2.48.3
cp unison /usr/local/sbin/
cp unison /usr/bin/
cd /opt
rm -rf unison/

Unison offers many available options.  Typing unison -doc or unison -help provides a comprehensive list.

Usage: unison [options]
    or unison root1 root2 [options]
    or unison profilename [options]

Basic options:
 -auto              automatically accept default (nonconflicting) actions
 -batch             batch mode: ask no questions at all
 -doc xxx           show documentation ('-doc topics' lists topics)
 -fat               use appropriate options for FAT filesystems
 -group             synchronize group attributes
 -ignore xxx        add a pattern to the ignore list
 -ignorenot xxx     add a pattern to the ignorenot list
 -nocreation xxx    prevent file creations on one replica
 -nodeletion xxx    prevent file deletions on one replica
 -noupdate xxx      prevent file updates and deletions on one replica
 -owner             synchronize owner
 -path xxx          path to synchronize
 -perms n           part of the permissions which is synchronized
 -root xxx          root of a replica (should be used exactly twice)
 -silent            print nothing except error messages
 -terse             suppress status messages
 -testserver        exit immediately after the connection to the server
 -times             synchronize modification times
 -version           print version and exit

Advanced options:
 -addprefsto xxx    file to add new prefs to
 -addversionno      add version number to name of unison on server
 -backup xxx        add a pattern to the backup list
 -backupcurr xxx    add a pattern to the backupcurr list
 -backupcurrnot xxx add a pattern to the backupcurrnot list
 -backupdir xxx     directory for storing centralized backups
 -backuploc xxx     where backups are stored ('local' or 'central')
 -backupnot xxx     add a pattern to the backupnot list
 -backupprefix xxx  prefix for the names of backup files
 -backups           keep backup copies of all files (see also 'backup')
 -backupsuffix xxx  a suffix to be added to names of backup files
 -clientHostName xxx set host name of client
 -confirmbigdel     ask about whole-replica (or path) deletes (default true)
 -confirmmerge      ask for confirmation before committing results of a merge
 -contactquietly    suppress the 'contacting server' message during startup
 -copymax n         maximum number of simultaneous copyprog transfers
 -copyonconflict    keep copies of conflicting files
 -copyprog xxx      external program for copying large files
 -copyprogrest xxx  variant of copyprog for resuming partial transfers
 -copyquoterem xxx  add quotes to remote file name for copyprog (true/false/default)
 -copythreshold n   use copyprog on files bigger than this (if >=0, in Kb)
 -debug xxx         debug module xxx ('all' -> everything, 'verbose' -> more)
 -diff xxx          set command for showing differences between files
 -dontchmod         when set, never use the chmod system call
 -dumbtty           do not change terminal settings in text UI
 -fastcheck xxx     do fast update detection (true/false/default)
 -fastercheckUNSAFE skip computing fingerprints for new files (experts only!)
 -follow xxx        add a pattern to the follow list
 -force xxx         force changes from this replica to the other
 -forcepartial xxx  add a pattern to the forcepartial list
 -halfduplex        force half-duplex communication with the server
 -height n          height (in lines) of main window in graphical interface
 -host xxx          bind the socket to this host name in server socket mode
 -ignorearchives    ignore existing archive files
 -ignorecase xxx    identify upper/lowercase filenames (true/false/default)
 -ignoreinodenumbers ignore inode number changes when detecting updates
 -ignorelocks       ignore locks left over from previous run (dangerous!)
 -immutable xxx     add a pattern to the immutable list
 -immutablenot xxx  add a pattern to the immutablenot list
 -key xxx           define a keyboard shortcut for this profile (in some UIs)
 -killserver        kill server when done (even when using sockets)
 -label xxx         provide a descriptive string label for this profile
 -links xxx         allow the synchronization of symbolic links (true/false/default)
 -log               record actions in logfile (default true)
 -logfile xxx       logfile name
 -maxbackups n      number of backed up versions of a file
 -maxerrors n       maximum number of errors before a directory transfer is aborted
 -maxsizethreshold n prevent transfer of files bigger than this (if >=0, in Kb)
 -maxthreads n      maximum number of simultaneous file transfers
 -merge xxx         add a pattern to the merge list
 -mountpoint xxx    abort if this path does not exist
 -nocreationpartial xxx add a pattern to the nocreationpartial list
 -nodeletionpartial xxx add a pattern to the nodeletionpartial list
 -noupdatepartial xxx add a pattern to the noupdatepartial list
 -numericids        don't map uid/gid values by user/group names
 -prefer xxx        choose this replica's version for conflicting changes
 -preferpartial xxx add a pattern to the preferpartial list
 -repeat xxx        synchronize repeatedly (text interface only)
 -retry n           re-try failed synchronizations N times (text ui only)
 -rootalias xxx     register alias for canonical root names
 -rsrc xxx          synchronize resource forks (true/false/default)
 -rsync             activate the rsync transfer mode (default true)
 -selftest          run internal tests and exit
 -servercmd xxx     name of unison executable on remote server
 -showarchive       show 'true names' (for rootalias) of roots and archive
 -socket xxx        act as a server on a socket
 -sortbysize        list changed files by size, not name
 -sortfirst xxx     add a pattern to the sortfirst list
 -sortlast xxx      add a pattern to the sortlast list
 -sortnewfirst      list new before changed files
 -sshargs xxx       other arguments (if any) for remote shell command
 -sshcmd xxx        path to the ssh executable
 -stream            use a streaming protocol for transferring file contents (default true)
 -ui xxx            select UI ('text' or 'graphic'); command-line only
 -unicode xxx       assume Unicode encoding in case insensitive mode
 -watch             when set, use a file watcher process to detect changes (default true)
 -xferbycopying     optimize transfers using local copies (default true)

unison: option `-doc' needs an argument.

Local Synchronization Example
Here is a sample example of a local directory synchronization.  Create two test directories and create three files in one of the directories.

mkdir /tmp/test{1,2}
cd /tmp/test1
touch file{1,2,3}

Use unison without any prompts to synchronize the directories.

unison -batch /tmp/test1 /tmp/test2

Using the command illustrated above, if either directory is altered, as if one or more files are changed, deleted, or added, the changes will be reflected on both sides.  As a test, I altered both examples of file2 with different contents each.  This file was skipped.

Remote Synchronization
Using SSH to connect to the remote server without a prompt for a password requires key generation.  Both the source and target hosts require a copy of unison to work. According to one site, the same version of Unison will need to be installed on both servers.

echo -e | ssh-keygen
ssh-copy-id -i .ssh/ root@remotehost
ssh root@remotehost

Use unison without any prompts to synchronize the directories, this is as simple as it gets.

unison -batch /tmp/test1 ssh://remotehost//tmp/test1

For this example, the copy source is a CentOS 7 install, while the target is a CentOS 6 install of Linux.  Following the steps above, downloading and compiling a copy of Unison made the synchronization possible.