3

Does Linux have the capability to use "junctioned" symbolic links? I'm not sure if this is an actual term or not, so let me explain the concept.

I have a git repository containing all my configuration dot files in ~/dotfiles. I use symbolic links into this directory in order to "activate" them. For example, by executing ln -s ~/dotfiles/bash/bash_profile ~/.bash_profile to produce the link:

~/.bash_profile -> ~/dotfiles/bash/bash_profile

However, I find myself in a situation where I want to combine the contents of multiple files. For example, I want the ~/.bash_profile symbolic link to point to two separate files, one for each project. E.g.:

~/.bash_profile
(1) -> ~/dotfiles/bash/bash_profile
(2) -> ~/dotfiles/proj/bash_profile

I know I can simply concatenate the two files (e.g., cat ~/dotfiles/{bash,proj}/bash_profile > ~/.bash_profile), but if I can do the same thing with symbolic links, I would prefer to.

I imagine that if such a feature exists (Nix is pretty huge), then under the hood it would have to map the two different files together, hiding all sorts of complexities under the hood (mapping file offsets of all non-first "mapped" files, locking all files when writing to the junctioned symbolic link, etc, etc).

If such a feature doesn't exist, are there are plans to implement it?

3
  • For shell scripts, you could write a wrapper, that include both of the other 2 scripts. Commented Feb 23, 2016 at 23:06
  • There may be a fuse file-system that does it. (they are a bit like hurd translators). Examples are mount on directory zzzz an unziper of zzzz.zip Commented Feb 23, 2016 at 23:08
  • 1
    From my perspective I'd rather create a couple of commands that set up the environment the way it needed to be for that particular project. The .bashrc would remain generic and the project specifics would live elsewhere. You could even include different directories in the PATH depending on which project was active at that moment in time. You could also have both projects active simultaneously in different terminal windows Commented Mar 14, 2017 at 0:20

2 Answers 2

3

Symbolic links just say “go look for this file somewhere else”. The content of a symbolic link is the same as the content of its target. So no, symbolic links can't do that. I suggest not trying to look for a feature that's related to symbolic links, because what you're after isn't. I would not have understood what you wanted from the term “junctioned symbolic link”, and even after seeing what you want I have no idea why you call it that.

You want to have files whose content is the result of combining the contents of multiple files. That means some part of the system has to be able to perform that combination, and you have to describe the kind of combination you want (concatenation, if I understand correctly).

Modern unix systems have a way to make arbitrary data appear as a file, independently of how it's stored: FUSE. With FUSE, every operation on a file (create, open, read, write, list directory, etc.) invokes some code in a program, and that code can do whatever you want. See Create a virtual file that is actually a command. You could try out scriptfs or fuseflt, or if you're feeling ambitious, roll your own.

For this use case, I don't think dynamic generation is the way to go. It's somewhat complicated, and won't work everywhere (FUSE isn't always accessible to non-root users, and isn't available at all on some systems such as Windows, even with Cygwin). I recommend that you use the same approach that I use: for files that have some kind of include facility (.bash_profile, .gitconfig, …), use that; for other files, when you've modified one of the constituent files, type make (or whatever build system you prefer) to regenerate the files that applications read.

1

Modular config files as a text processing function

What you're asking for is more properly text processing than file processing, and it's largely dependent on what program is consuming the text files.

The traditional straightforward way to do what you want is to have a top-level file that includes other files in a modular way, such as:

~/.bash_profile:

source ~/dotfiles/bash/bash_profile
source ~/dotfiles/proj/bash_profile

A benefit is that you can comment out lines to make temporary changes, and you keep the intent obvious:

source ~/dotfiles/bash/bash_profile
# source ~/dotfiles/proj/bash_profile
source ~/dotfiles/proj2/bash_profile

Managing scripts with directories of symbolic links

But if you really feel like using symbolic links to manage a collection of bash configuration files, there's a well-established way to do it with very little "glue" on top of existing symlinks.

Try creating a directory called (e.g.) ~/.bash_profiles, which contains links with names like 00base (pointing to ~/dotfiles/bash/bash_profile) and 10proj (pointing to ~/dotfiles/proj/bash_profile), then putting this in ~/.bash_profile :

for file in ~/.bash_profiles/* ; do source $file ; done

Then you can activate, deactivate, and reorder the config files by manipulating symbolic links and without editing any files. It works because the expansion of ~/.bash_profiles/* is sorted lexically by bash.

This is essentially how classic Unix/Linux init allows management of system startup scripts. It's probably rather overkill for bash unless you have a very complex set of customizations to selectively load based on the project you're working on.

Not the answer you're looking for? Browse other questions tagged .