Roland's homepage

My random knot in the Web

Managing configuration files with ‘deploy’

The deploy script is a program for managing configuration files. This script grew out of my need for a multi-functional installer for configuration files. I tend to keep those files in a separate git repository rather than changing my $HOME into a git repository.


On UNIX, there is the venerable install program initially meant to install binaries. My first installers were typically shell scripts which basically were a list of calls to install(1). While this works well it didn’t completely fit my needs. Because next to purely installing a file somewhere, I wanted to be able to do more things;

  • Check for differences between the files in the repository and those in the installed location.
  • Print diffs between the files in the repository and those in the installed location.
  • Run arbitrary commands after a file was succesfully installed

I could of course do this with a makefile and this approach would be extremely flexible. But writing and maintaining such a Makefile would be quite cumbersome. Every file would need to have its own dependency line. And they would all have to be grouped added to a super target at the beginning of the makefile.

How it works

The deploy command is meant to be run from a color terminal; it uses ANSI escape codes to color its output.

It is meant to be used from the root of e.g. a git repository. When started, deploy looks for and reads the file named filelist.$USER in the directory from which deploy is run. So when run by a user named “jdoe” it would look for a file filelist.jdoe. This is suitable for installing files in the directory tree owned by jdoe. For installing files system wide (e.g. in /etc or /usr/local/etc), create filelist.root and run deploy as the root user.

file format

In these file lists, lines that have a ‘#’ as the first non-whitespace characters are skipped as comments. The first non-comment line must contain a list of fully qualified host names for which this file is valid. If the name of the host where deploy is run is not in that list, it will quit.

The other non comment lines all have the same format:

<source path> <mode> <destination path> <post-install commands>
  • The source path is path relative from the directory where deploy is called from. It may not contain whitespace.
  • The mode is an octal number indicating the permissions of the destination file, see chmod(1).
  • The destination path should be an absolute path including the name of the installed file. It may not contain whitespace. The reason for including the filename is so that you can e.g. install a file profile as /home/jdoe/.profile.
  • The rest of the line is considered the post-install commands. This may be empty and may contain spaces.


The ‘deploy’ program has tree sub-commands or modes;

  • check: Generate a list of files that are different from the installed files. If the verbose option (-v) is used, it lists for all files if they need installing or not.
  • diff: Generate a colored diff between the files in the repository and the installed files.
  • install: Install the files in their destinations and run the post-install commands.


The file filelist.jdoe in a setup directory contains the following lines among others;

../shared/fetchmailrc  400 /home/jdoe/.fetchmailrc

This installs the configuration file for fetchmail and makes sure that only the owner can read it. Note how a relative path is used for the source, and an absolute path is used for the destination. The first is for convenience, the second for preventing mistakes.

The following line is an example of using post-install commands;

Xresources  644  /home/jdoe/.Xresources  xrdb -load /home/jdoe/.Xresources

This reloads the X resources into the X server after installing them.

Below is a usage example;

rlyeh:~/setup/rlyeh> ./deploy check
The file '../shared/muttrc' differs from '/home/jdoe/.muttrc'.

rlyeh:~/setup/rlyeh> ./deploy diff
The file '../shared/muttrc' differs from '/home/jdoe/.muttrc'.
--- /home/jdoe/.muttrc
+++ ../shared/muttrc
@@ -1,5 +1,5 @@
 # /home/jdoe/.muttrc
-# $Date: 2014-12-19 00:46:55 +0100 $
+# $Date: 2014-12-29 02:07:58 +0100 $

 # Settings
@@ -76,12 +76,11 @@
 set crypt_replyencrypt = yes
 set crypt_replysign = yes
 set crypt_replysignencrypted = yes
-set crypt_use_gpgme = yes
 set crypt_verify_sig = yes
 set pgp_good_sign="^gpgv?: Good signature from "
 set pgp_sign_as = B37C45E8
 set pgp_timeout = 3600
+set pgp_use_gpg_agent=yes

 # S/MIME stuff.

rlyeh:~/setup/rlyeh> ./deploy install
File '../shared/muttrc' was successfully installed as '/home/jdoe/.muttrc'.


As of May 2015, the source code repository is now available on github.


The deploy program was written for Python 3 (developed and tested with python3.4). It has no dependencies outside of Python’s standard library.


The script should be compatible with both Python 2 and Python 3. But it uses the latter by default. Change the first line of the script if you want to use Python 2. In that case you should also add the following line to the script:

from __future__ import print_function


UNIX-like operating systems

This includes Linux, all BSD variants, Apple’s OS X.

For a system-wide installation:

  • Make sure you don’t already have an identically named program installed!
  • Copy the script to a location in your path as deploy
  • Make it executable.

For example

# install /usr/local/bin/deploy

If you want to install it locally, just copy it to where you need it and make it executable.


If your system doesn’t have \usr\bin\env, or if your Python 3 is not in your $PATH, modify the first line of the deploy program to point to the location of the Python 3 program before installing it.


Copy to the scripts directory of your Python 3 installation. Since I do not use MS windows in my development environment I’m not able to give more specific advice.

Instead of the standard cmd.exe shell, I would suggest you use e.g. the git BASH that comes with MSYS git distribution.

For comments, please send me an e-mail.

Related articles

←  Opening files from the command line img4latex  →