Stow is a simple way to manage software packages that were built from source, or any package that lets you specify a destination directory. Essentially, it is just a huge wrapper around ln, but it has hordes of sanity checks thrown in the mix.
If you've ever installed a piece of software from source under UNIX, you probably understand
that things get can out of control really quick. If you only install a small number of packages,
you are pretty safe just letting the software's configuration defaults (hopefully cobbled together with
autoconf and automake) "do their thing". This usually results in software getting
dumped to /usr/local/, and in rare cases / or /usr. The directories off of
/, /usr, and /usr/local generally include some combination of:
etc
bin
include
lib
libexec
man
sbin
share
var
For demonstration purposes, let us say I have a piece of software called 'foobar' which is currently
at version 1.0. I download the source (http://www.foobar.com/downloads/foobar-1.0.tar.gz), do a
very-very simple configuration and installation (tar -zxvf foobar-1.0.tar.gz; cd foobar-1.0;
./configure && make && make install). The installation copies the following files to their
respective directories in /usr/local/:
Great. You just successfully installed foobar. You use it for a month. During that time,
you install 15 other packages from source using similar techniques. Then a little bird whispers in
your ear and tells you that foobar-1.3 has come out and fixes a serious security hole and
eliminates a few cosmetic bugs.
etc/foobar.cfg
bin/foobar
include/foobar.h
lib/foobar.so
man/man8/foobar.8
No problem, right? Just download and install the latest version just like you did with 1.0. Wait a
minute, it appears the developers have mixed things up a bit. The installation now creates the
following layout under /usr/local:
See the problems? Here are a few:
etc/foobar.conf
bin/foobar
lib/foobar.a
man/man3/foobar.3
/usr/local/stow/foobar-1.0/etc/foobar.cfg /usr/local/stow/foobar-1.0/bin/foobar /usr/local/stow/foobar-1.0/include/foobar.h /usr/local/stow/foobar-1.0/lib/foobar.so /usr/local/stow/foobar-1.0/man/man8/foobar.8
/usr/local/etc/foobar.cfg --> /usr/local/stow/foobar-1.0/etc/foobar.cfg /usr/local/bin/foobar --> /usr/local/stow/foobar-1.0/bin/foobar /usr/local/include/foobar.h --> /usr/local/stow/foobar-1.0/include/foobar.h /usr/local/lib/foobar.so --> /usr/local/stow/foobar-1.0/lib/foobar.so /usr/local/man/man8/foobar.8 --> /usr/local/stow/foobar-1.0/man/man8/foobar.8
tar -zxvf foobar-1.0.tar.gz cd foobar-1.0 ./configure --prefix=/usr/local/stow/foobar-1.0 make make install cd /usr/local/stow stow foobar-1.0
cd /usr/local/stow
stow -D foobar-1.0
# stow removed all the symlinks from /usr/local/{etc,bin,include,lib,man}. foobar is no longer in anyone's $PATH
# foobar-1.0 still exists, but is saved safely away in /usr/local/stow/foobar-1.0
cd /usr/local/src
tar -zxvf foobar-1.3.tar.gz
cd foobar-1.3
./configure --prefix=/usr/local/stow/foobar-1.3
make && make install
cd /usr/local/stow
stow foobar-1.3
# stow now put the appropriate symlinks into /usr/local/{etc,bin,lib,man}
Here is an example of a system that was recently installed (Slackware Linux 8.0). After installation, the owner of the machine decided to install a number of packages and has since updated some of them. Here is what /usr/local/stow looks like:
[/usr/local/stow]$ ls -l total 172 drwxr-xr-x 4 root root 4096 Dec 13 13:50 Bitchx-75p3/ drwxr-xr-x 7 root root 4096 Mar 13 10:40 SDL-1.2.3/ drwxr-xr-x 5 root root 4096 Mar 13 10:41 SDL_image-1.2.1/ drwxr-xr-x 5 root root 4096 Mar 13 10:46 SDL_mixer-1.2.1/ drwxr-xr-x 5 root root 4096 Mar 13 10:55 SDL_mixer_patched/ drwxr-xr-x 5 root root 4096 Feb 20 10:55 arpwatch-2.1a4/ drwxr-xr-x 4 root root 4096 Nov 18 12:14 aterm-0.4.2/ drwxr-xr-x 5 root root 4096 Feb 18 18:29 bc-1.06/ drwxr-xr-x 6 root root 4096 Feb 15 09:48 curl-7.9.4/ drwxr-xr-x 6 root root 4096 Nov 18 13:40 db-3.3.11/ drwxr-xr-x 6 root root 4096 Jan 9 11:29 dia-0.88/ drwxr-xr-x 5 root root 4096 Nov 18 13:54 dsniff-2.3/ drwxr-xr-x 6 root root 4096 Dec 7 16:57 ethereal-0.8.20/ drwxr-xr-x 6 root root 4096 Jan 3 12:09 ethereal-0.9.0/ drwxr-xr-x 6 root root 4096 Jan 18 17:00 ettercap-0.6.3.1/ drwxr-xr-x 4 root root 4096 Nov 18 23:18 firewalk-1.0/ drwxr-xr-x 5 root root 4096 Dec 4 15:27 freetds-0.53/ drwxr-xr-x 6 root root 4096 Nov 18 12:10 fvwm-2.4.3/ drwxr-xr-x 6 root root 4096 Nov 18 12:26 gaim-0.48/ drwxr-xr-x 5 root root 4096 Nov 26 08:22 gd-1.8.4/ drwxr-xr-x 5 root root 4096 Feb 6 06:55 kismet-1.4/ drwxr-xr-x 4 root root 4096 Jan 2 19:33 libfaim-20010918/ drwxr-xr-x 6 root root 4096 Dec 20 12:24 libnasl/ drwxr-xr-x 6 root root 4096 Nov 18 12:40 libnet-1.0.2a/ drwxr-xr-x 5 root root 4096 Nov 18 13:12 libnids-1.16/ drwxr-xr-x 4 root root 4096 Nov 18 12:56 libpcap-0.4/ drwxr-xr-x 5 root root 4096 Dec 7 16:34 libpcap-0.7.0/ drwxr-xr-x 4 root root 4096 Nov 18 14:30 lsof-4.60/ drwxr-xr-x 3 root root 4096 Nov 18 14:34 nc-1.10/ drwxr-xr-x 9 root root 4096 Dec 20 12:31 nessus-core-1.0.10/ drwxr-xr-x 6 root root 4096 Dec 20 12:22 nessus-libraries-1.0.10/ drwxr-xr-x 5 root root 4096 Dec 20 12:35 nessus-plugins-1.0.10/ drwxr-xr-x 8 root root 4096 Dec 30 23:58 net-snmp-5.0.pre1/ drwxr-xr-x 5 root root 4096 Nov 18 12:31 nmap-2.54BETA30/ drwxr-xr-x 8 root root 4096 Feb 6 06:10 openssh-3.0.2p1/ drwxr-xr-x 8 root root 4096 Mar 9 11:59 openssh-3.1p1/ drwxr-xr-x 4 root root 4096 Nov 25 17:55 snort-1.8.2/ drwxr-xr-x 3 root root 4096 Dec 7 22:04 ssidsniff-0.33/ drwxr-xr-x 5 root root 4096 Jan 17 15:53 sudo-1.6.5p1/ drwxr-xr-x 4 root root 4096 Dec 7 16:44 tcpdump-0.7.0/ drwxr-xr-x 5 root root 4096 Dec 7 21:59 wireless-tools-22/ drwxr-xr-x 7 root root 4096 Nov 26 06:01 xine-lib-0.9.4/ drwxr-xr-x 5 root root 4096 Nov 26 06:04 xine-ui-0.9.4/
[/usr/local/bin]$ ls -l total 16 lrwxrwxrwx 1 root root 30 Dec 13 13:50 BitchX -> ../stow/Bitchx-75p3/bin/BitchX* lrwxrwxrwx 1 root root 35 Dec 13 13:50 BitchX-75p3 -> ../stow/Bitchx-75p3/bin/BitchX-75p3* lrwxrwxrwx 1 root root 34 Nov 18 12:10 FvwmCommand -> ../stow/fvwm-2.4.3/bin/FvwmCommand* lrwxrwxrwx 1 root root 29 Nov 18 12:14 aterm -> ../stow/aterm-0.4.2/bin/aterm* lrwxrwxrwx 1 root root 22 Feb 18 18:29 bc -> ../stow/bc-1.06/bin/bc* lrwxrwxrwx 1 root root 28 Nov 26 08:22 bdftogd -> ../stow/gd-1.8.4/bin/bdftogd* lrwxrwxrwx 1 root root 37 Nov 18 14:11 berkeley_db_svc -> ../stow/db-3.3.11/bin/berkeley_db_svc* lrwxrwxrwx 1 root root 23 Dec 20 12:25 bin -> ../stow/libnasl/bin/bin* lrwxrwxrwx 1 root root 27 Feb 15 09:48 curl -> ../stow/curl-7.9.4/bin/curl* lrwxrwxrwx 1 root root 34 Feb 15 09:48 curl-config -> ../stow/curl-7.9.4/bin/curl-config* lrwxrwxrwx 1 root root 32 Nov 18 13:40 db_archive -> ../stow/db-3.3.11/bin/db_archive* lrwxrwxrwx 1 root root 35 Nov 18 13:40 db_checkpoint -> ../stow/db-3.3.11/bin/db_checkpoint* lrwxrwxrwx 1 root root 33 Nov 18 13:40 db_deadlock -> ../stow/db-3.3.11/bin/db_deadlock* lrwxrwxrwx 1 root root 29 Nov 18 13:40 db_dump -> ../stow/db-3.3.11/bin/db_dump* lrwxrwxrwx 1 root root 29 Nov 18 13:40 db_load -> ../stow/db-3.3.11/bin/db_load* lrwxrwxrwx 1 root root 33 Nov 18 13:40 db_printlog -> ../stow/db-3.3.11/bin/db_printlog* lrwxrwxrwx 1 root root 32 Nov 18 13:40 db_recover -> ../stow/db-3.3.11/bin/db_recover* lrwxrwxrwx 1 root root 29 Nov 18 13:40 db_stat -> ../stow/db-3.3.11/bin/db_stat* lrwxrwxrwx 1 root root 32 Nov 18 13:40 db_upgrade -> ../stow/db-3.3.11/bin/db_upgrade* lrwxrwxrwx 1 root root 31 Nov 18 13:40 db_verify -> ../stow/db-3.3.11/bin/db_verify* lrwxrwxrwx 1 root root 22 Feb 18 18:29 dc -> ../stow/bc-1.06/bin/dc* lrwxrwxrwx 1 root root 24 Jan 9 11:29 dia -> ../stow/dia-0.88/bin/dia* lrwxrwxrwx 1 root root 34 Jan 3 12:11 editcap -> ../stow/ethereal-0.9.0/bin/editcap* lrwxrwxrwx 1 root root 46 Dec 30 23:58 encode_keychange -> ../stow/net-snmp-5.0.pre1/bin/encode_keychange* lrwxrwxrwx 1 root root 35 Jan 3 12:11 ethereal -> ../stow/ethereal-0.9.0/bin/ethereal* lrwxrwxrwx 1 root root 33 Nov 18 23:19 firewalk -> ../stow/firewalk-1.0/bin/firewalk* lrwxrwxrwx 1 root root 34 Nov 18 12:10 fvwm-config -> ../stow/fvwm-2.4.3/bin/fvwm-config* lrwxrwxrwx 1 root root 40 Nov 18 12:10 fvwm-menu-desktop -> ../stow/fvwm-2.4.3/bin/fvwm-menu-desktop* lrwxrwxrwx 1 root root 42 Nov 18 12:10 fvwm-menu-directory -> ../stow/fvwm-2.4.3/bin/fvwm-menu-directory* lrwxrwxrwx 1 root root 42 Nov 18 12:10 fvwm-menu-headlines -> ../stow/fvwm-2.4.3/bin/fvwm-menu-headlines* lrwxrwxrwx 1 root root 38 Nov 18 12:10 fvwm-menu-xlock -> ../stow/fvwm-2.4.3/bin/fvwm-menu-xlock* lrwxrwxrwx 1 root root 28 Nov 18 12:10 fvwm2 -> ../stow/fvwm-2.4.3/bin/fvwm2* lrwxrwxrwx 1 root root 37 Nov 18 12:10 fvwm24_convert -> ../stow/fvwm-2.4.3/bin/fvwm24_convert* lrwxrwxrwx 1 root root 30 Nov 18 12:10 fvwmbug -> ../stow/fvwm-2.4.3/bin/fvwmbug* lrwxrwxrwx 1 root root 26 Nov 18 12:27 gaim -> ../stow/gaim-0.48/bin/gaim* lrwxrwxrwx 1 root root 31 Nov 26 08:22 gd2copypal -> ../stow/gd-1.8.4/bin/gd2copypal* lrwxrwxrwx 1 root root 29 Nov 26 08:22 gd2topng -> ../stow/gd-1.8.4/bin/gd2topng* lrwxrwxrwx 1 root root 32 Nov 26 08:22 gdparttopng -> ../stow/gd-1.8.4/bin/gdparttopng* lrwxrwxrwx 1 root root 28 Nov 26 08:22 gdtopng -> ../stow/gd-1.8.4/bin/gdtopng* lrwxrwxrwx 1 root root 34 Jan 3 12:11 idl2eth -> ../stow/ethereal-0.9.0/bin/idl2eth* lrwxrwxrwx 1 root root 29 Feb 6 06:46 kismet -> ../stow/kismet-1.4/bin/kismet* lrwxrwxrwx 1 root root 39 Nov 18 12:40 libnet-config -> ../stow/libnet-1.0.2a/bin/libnet-config* lrwxrwxrwx 1 root root 26 Nov 18 14:30 lsof -> ../stow/lsof-4.60/bin/lsof* lrwxrwxrwx 1 root root 35 Jan 3 12:11 mergecap -> ../stow/ethereal-0.9.0/bin/mergecap* lrwxrwxrwx 1 root root 35 Dec 30 23:09 mib2c -> ../stow/net-snmp-5.0.pre1/bin/mib2c* lrwxrwxrwx 1 root root 31 Dec 20 12:25 nasl-config -> ../stow/libnasl/bin/nasl-config* lrwxrwxrwx 1 root root 22 Nov 18 14:35 nc -> ../stow/nc-1.10/bin/nc* lrwxrwxrwx 1 root root 37 Dec 20 12:31 nessus -> ../stow/nessus-core-1.0.10/bin/nessus* lrwxrwxrwx 1 root root 49 Dec 20 12:23 nessus-config -> ../stow/nessus-libraries-1.0.10/bin/nessus-config* lrwxrwxrwx 1 root root 45 Dec 30 23:09 net-snmp-config -> ../stow/net-snmp-5.0.pre1/bin/net-snmp-config* lrwxrwxrwx 1 root root 33 Dec 7 22:04 nldump -> ../stow/ssidsniff-0.33/bin/nldump* lrwxrwxrwx 1 root root 32 Nov 18 12:31 nmap -> ../stow/nmap-2.54BETA30/bin/nmap* lrwxrwxrwx 1 root root 34 Nov 18 12:31 nmapfe -> ../stow/nmap-2.54BETA30/bin/nmapfe* lrwxrwxrwx 1 root root 35 Dec 7 22:04 pcapdump -> ../stow/ssidsniff-0.33/bin/pcapdump* lrwxrwxrwx 1 root root 34 Dec 7 22:04 pcapset -> ../stow/ssidsniff-0.33/bin/pcapset* lrwxrwxrwx 1 root root 37 Mar 13 10:55 playmus -> ../stow/SDL_mixer_patched/bin/playmus* lrwxrwxrwx 1 root root 38 Mar 13 10:55 playwave -> ../stow/SDL_mixer_patched/bin/playwave* lrwxrwxrwx 1 root root 28 Nov 26 08:22 pngtogd -> ../stow/gd-1.8.4/bin/pngtogd* lrwxrwxrwx 1 root root 29 Nov 26 08:22 pngtogd2 -> ../stow/gd-1.8.4/bin/pngtogd2* lrwxrwxrwx 1 root root 29 Mar 9 12:07 scp -> ../stow/openssh-3.1p1/bin/scp* lrwxrwxrwx 1 root root 30 Dec 13 13:50 scr-bx -> ../stow/Bitchx-75p3/bin/scr-bx* lrwxrwxrwx 1 root root 32 Mar 13 10:41 sdl-config -> ../stow/SDL-1.2.3/bin/sdl-config* lrwxrwxrwx 1 root root 30 Mar 9 12:07 sftp -> ../stow/openssh-3.1p1/bin/sftp* lrwxrwxrwx 1 root root 37 Mar 13 10:41 showimage -> ../stow/SDL_image-1.2.1/bin/showimage* lrwxrwxrwx 1 root root 32 Mar 9 12:07 slogin -> ../stow/openssh-3.1p1/bin/slogin* lrwxrwxrwx 1 root root 41 Dec 30 23:58 snmpbulkget -> ../stow/net-snmp-5.0.pre1/bin/snmpbulkget* lrwxrwxrwx 1 root root 42 Dec 30 23:58 snmpbulkwalk -> ../stow/net-snmp-5.0.pre1/bin/snmpbulkwalk* lrwxrwxrwx 1 root root 39 Dec 30 23:09 snmpcheck -> ../stow/net-snmp-5.0.pre1/bin/snmpcheck* lrwxrwxrwx 1 root root 38 Dec 30 23:09 snmpconf -> ../stow/net-snmp-5.0.pre1/bin/snmpconf* lrwxrwxrwx 1 root root 39 Dec 30 23:58 snmpdelta -> ../stow/net-snmp-5.0.pre1/bin/snmpdelta* lrwxrwxrwx 1 root root 36 Dec 30 23:58 snmpdf -> ../stow/net-snmp-5.0.pre1/bin/snmpdf* lrwxrwxrwx 1 root root 37 Dec 30 23:58 snmpget -> ../stow/net-snmp-5.0.pre1/bin/snmpget* lrwxrwxrwx 1 root root 41 Dec 30 23:58 snmpgetnext -> ../stow/net-snmp-5.0.pre1/bin/snmpgetnext* lrwxrwxrwx 1 root root 40 Dec 30 23:58 snmpinform -> ../stow/net-snmp-5.0.pre1/bin/snmpinform* lrwxrwxrwx 1 root root 41 Dec 30 23:58 snmpnetstat -> ../stow/net-snmp-5.0.pre1/bin/snmpnetstat* lrwxrwxrwx 1 root root 37 Dec 30 23:58 snmpset -> ../stow/net-snmp-5.0.pre1/bin/snmpset* lrwxrwxrwx 1 root root 40 Dec 30 23:58 snmpstatus -> ../stow/net-snmp-5.0.pre1/bin/snmpstatus* lrwxrwxrwx 1 root root 39 Dec 30 23:58 snmptable -> ../stow/net-snmp-5.0.pre1/bin/snmptable* lrwxrwxrwx 1 root root 38 Dec 30 23:58 snmptest -> ../stow/net-snmp-5.0.pre1/bin/snmptest* lrwxrwxrwx 1 root root 43 Dec 30 23:58 snmptranslate -> ../stow/net-snmp-5.0.pre1/bin/snmptranslate* lrwxrwxrwx 1 root root 38 Dec 30 23:58 snmptrap -> ../stow/net-snmp-5.0.pre1/bin/snmptrap* lrwxrwxrwx 1 root root 37 Dec 30 23:58 snmpusm -> ../stow/net-snmp-5.0.pre1/bin/snmpusm* lrwxrwxrwx 1 root root 38 Dec 30 23:58 snmpvacm -> ../stow/net-snmp-5.0.pre1/bin/snmpvacm* lrwxrwxrwx 1 root root 38 Dec 30 23:58 snmpwalk -> ../stow/net-snmp-5.0.pre1/bin/snmpwalk* lrwxrwxrwx 1 root root 29 Nov 25 17:55 snort -> ../stow/snort-1.8.2/bin/snort* lrwxrwxrwx 1 root root 29 Mar 9 12:07 ssh -> ../stow/openssh-3.1p1/bin/ssh* lrwxrwxrwx 1 root root 33 Mar 9 12:07 ssh-add -> ../stow/openssh-3.1p1/bin/ssh-add* lrwxrwxrwx 1 root root 35 Mar 9 12:07 ssh-agent -> ../stow/openssh-3.1p1/bin/ssh-agent* lrwxrwxrwx 1 root root 36 Mar 9 12:07 ssh-keygen -> ../stow/openssh-3.1p1/bin/ssh-keygen* lrwxrwxrwx 1 root root 37 Mar 9 12:07 ssh-keyscan -> ../stow/openssh-3.1p1/bin/ssh-keyscan* lrwxrwxrwx 1 root root 36 Dec 7 22:04 ssidsniff -> ../stow/ssidsniff-0.33/bin/ssidsniff* -rwxr-xr-x 1 root root 14000 Nov 18 12:06 stow* lrwxrwxrwx 1 root root 29 Jan 17 15:53 sudo -> ../stow/sudo-1.6.5p1/bin/sudo* lrwxrwxrwx 1 root root 36 Jan 3 12:11 tethereal -> ../stow/ethereal-0.9.0/bin/tethereal* lrwxrwxrwx 1 root root 36 Jan 3 12:11 text2pcap -> ../stow/ethereal-0.9.0/bin/text2pcap* lrwxrwxrwx 1 root root 35 Dec 30 23:09 tkmib -> ../stow/net-snmp-5.0.pre1/bin/tkmib* lrwxrwxrwx 1 root root 41 Dec 30 23:09 traptoemail -> ../stow/net-snmp-5.0.pre1/bin/traptoemail* lrwxrwxrwx 1 root root 27 Nov 26 08:22 webpng -> ../stow/gd-1.8.4/bin/webpng* lrwxrwxrwx 1 root root 29 Dec 13 13:50 wserv -> ../stow/Bitchx-75p3/bin/wserv* lrwxrwxrwx 1 root root 30 Nov 26 06:05 xine -> ../stow/xine-ui-0.9.4/bin/xine* lrwxrwxrwx 1 root root 38 Nov 26 06:02 xine-config -> ../stow/xine-lib-0.9.4/bin/xine-config* lrwxrwxrwx 1 root root 33 Nov 18 12:31 xnmap -> ../stow/nmap-2.54BETA30/bin/xnmap* lrwxrwxrwx 1 root root 30 Nov 18 12:10 xpmroot -> ../stow/fvwm-2.4.3/bin/xpmroot*