How to symlink folders and exclude certain files

Solution 1:

I assume you really mean "symlink everything inside the folder"...

Conceptually, you want something like:

for each file in base folder not in exclude list
    create symlink in target folder pointing back to base folder
done

bash logic to achieve this goes something like

#! /bin/bash

exclude=( "foo.conf" "bar.conf" )

for file in *; do
    for (( index = 0; index < ${#exclude[@]}; index++ )); do
        if [[ ${file} != ${exclude[${index}]} ]]; then
            ln -s ${file} ${target}/${file}
        fi  
    done
done

Assuming you don't know already, the Advanced Bash-Scripting Guide should give you enough to work out what globbing you want (perhaps find) and how to convert that to a function (perhaps a recursive one).

Solution 2:

You could (ab)use xstow. This program is designed to populate a forest of symbolic links, which is close to what you want. It doesn't have an option to exclude some files, but you can hack it, sort of. For each server:

  1. Create files that you want to exclude from this server. The contents don't matter, they just have to be easy to tell afterwards, so we'll make them all hard links to one particular file.
  2. (You don't mention this in your requirements but it's easy to fit in.) Symlink files that must have a server-specific contents from a hierarchy that contains only those files.
  3. Symlink files from the base install. Skip over any file that's already present.
  4. Remove the files we in fact wanted to exclude from this server.
cd .../targets/server1
touch .exclude
for x in files to exclude; do mkdir -p "$(dirname "$x")"; ln .exclude "$x"; done
xstow -d .../sources -t . server1-specific-files
xstow -f -d .../sources -t . base-install
find -samefile .exclude -exec rm {} +