Check out a free preview of the full Developer Productivity course

The "GNU Stow" Lesson is part of the full, Developer Productivity course featured in this preview video. Here's what you'd learn in this lesson:

ThePrimeagen introduces GNU Stow, demonstrates a directory structure, and walks through some examples of using stow including stowing a file, a directory, and two directories with similar paths. A student's question regarding how stow knows which directory to look at is also discussed in this segment.

Preview
Close

Transcript from the "GNU Stow" Lesson

[00:00:00]
>> I'm gonna primarily focus on stow and the reason why I'm focusing on stow is that it's incredibly simple. I really wanted this as part of my requirements because Ansible is really complex it can do a lot of things it can vault, it can install. It can do my SSH key, awesomeness, it can also become me, can do sudo operate like it just, it's built to really get my system up and running.

[00:00:22]
So I need something that's just really simple and so I wanted to have like the opposite side here. Stow only manages symlinks that is it are soft links as they may be called right there. You can also run it on different operating system. Meaning that you actually have the choice of what you do and don't stow.

[00:00:39]
So it actually does allow you to have like, hey, when I sell and it's a Mac, I want to know these things when I still and it's Ubuntu I want to do these things. If it's Windows subsystem, I wanna stow it this way, right? So you have different options that you can do.

[00:00:51]
So to follow along, I do recommend you if you want to, you should try following along. Apt install stow, brew installed stow, if you're using Arch Linux you probably already have stow or know what you're doing. So I'm just gonna just assume you've already, by the way me, you're better than me, I get it, you use Arch Linux.

[00:01:09]
By the way, some friends and I did start a group called FAAL, father's against Arch Linux. So if you use it, I just wanna let that I'm against it, all right, that's enough of that. So I'm gonna first jump over to the greatest program of all time commonly referred to as GIMP, here we go.

[00:01:24]
And this is obviously the superior drawing program, none other are as good as GIMP. For those that do know anything about it, it gets made fun of all the time. All right, so here we go, everything looks good. So when it comes to stowing, stowing operates on directories and files, so I'm gonna kind of create this imaginary directory structure.

[00:01:44]
Let's just say I have something called A that has a folder that has B in it. B is a folder that has C in it and C as a folder. Say some file now you're probably gonna first ask yourself, well, you have really great handwriting for using a mouse, you're right, I do.

[00:01:59]
Second, who names their folders A, B, and C, but for the sake of this, that's what we're doing. So I want you to have your attention right here on B. Now B is gonna be where we're at, we're gonna execute stow within this directory. So B is my stow directory, it's gonna go and attempt to stow C.

[00:02:21]
So C is gonna be the thing that is stowed. B is the stow directory and where is it gonna get stowed to now I know obviously you don't you're probably a little confused on the terminology. What does stowing mean? It'll become clear, I just wanted to make sure you first understand where things are going.

[00:02:37]
Lastly, it's gonna be going to A, so A is what is referred to as our target directory, B is our store directory, and C are the things we're storing. So let's kind of do this maybe in a little bit more sensible way. I'll actually give some real examples, so hopefully this becomes obvious.

[00:02:54]
So when I use the term target directory, you know what I mean, it means the parent of the directory that we're executing stow in. So let's go back here, let's go to I believe I have it in my Ansible. Let's just make sure it's not here, here I'm going to rm rf don't pretend it's not there, all right?

[00:03:10]
So we're gonna make a directory called target directory, right? So I'm gonna CD into my target directory. I'm then gonna make a directory that is gonna be called my, let's call it still or not. Yeah, our stow-dr, and so I'm gonna go into my stow-dr, and now I'm gonna make a directory called nvim.

[00:03:29]
How does that sound? There we go, so now I have a couple directories. And so now we're into a place where I'm in a place called target directory, stow directory, and there's a subfolder called nvim. So inside of nvim, let's just have a simple file called testfile. And in it, I'm gonna go hello, that's it, there we go.

[00:03:47]
So now if I go find starting right here, you'll notice that we have the nvim sub folder with a single file called testfile. And if we look it up my present working directory, we are currently in target directory, stow directory. So now if I call stow, which is the program, we just got done installing either using brew, or apt, or Pac-Man, or whatever you have.

[00:04:07]
Some next OS person is gonna stand up now neckbeard super long, tell me about the glories of next, I don't wanna hear about it. So anyways, so we have stow and we are going to go stow nvim, that's it. So no output happened, if I go find here, nothing seemed to change.

[00:04:24]
So what changed? Well, if you remember, if you recall, we have a target directory, which is the parents directory. So let's go back into here, and let's back it up, and let's find right here. So what are you gonna see in here? Well, you're gonna see something that's kind of interesting.

[00:04:39]
We now have something called testfile in the target directory. So what is testfile? So let's do a little ls-la, you'll notice that testfile, A, it's a symlink. So if you're wondering what a symlink is, that's what a symlink is, so it's a shortcut. So you'll see that the test file was just newly added, I did not add that, stow did.

[00:05:01]
Stow took the folder that I stowed and put it in to the target directory. And what it did is it used symlinks meaning it didn't copy over the file, it's just simply pointing to the previous one. So let's go back to our show directory and let's open it back up, we can see there's the test file.

[00:05:20]
And so let's add another file, but this time, let's add a directory let's pretend like we're actually creating a nvim config. So let's do the dot config, let's go into here and do nvim, and then inside of here let's do our init.vim. So this is normally where you would do it if you were on your desktop, or on your home directory, you do dot config, nvim and it dot nvim.

[00:05:42]
So let's go in here and I have this nice little dot file right here, so let's back it up. All right, so let's go back into our stow directory and go find. So this is now our new nvim test folder, it has nvim. It has that same test file that did exist, but it also has a config directory, a nvim directory, and an init.vim within the nvim.config directories.

[00:06:07]
So now when I call stow, and I do nvim, what do you think is gonna happen? So let's go back and let's do a find here. Now find remember, find it does not follow symlinks. So what you'll see is that we do have a test file and we do have a config folder, but that is it.

[00:06:24]
So when I go ls-la you'll notice that the config folder just points to the config folder in the nvim folder. It effectively found the lowest amount within the file tree that it could symlink to, and just simply symlinked it. It didn't go all the way down, it didn't create all the folders, it just went as low as possible and created that symlink.

[00:06:45]
Now obviously this could be a little bit problematic, so let's see what happens because there has to be a problem here, right? So let's go back into my store directory and let's create a new one called tmux up CS that's a file. We don't want a file, we want a directory tmux, there we go.

[00:06:59]
We have a directory called tmux, and inside of the directory called tmux. Let's have another dot config folder, right, so this now creates a collision, right? And inside of here, let's have tmux, and then we can ask them like tmux dot config, right, there we go. That's the directory, let's get rid of that, tmux conf, right?

[00:07:16]
All right, there we go, now we can just put it I don't know. Hello, we'll put hello again, hello from tmux conf. Just to make sure just in case we wanna look at that, so now let's stoke tmux. Now it didn't say any errors, it does create the symlinks, but where was the real question?

[00:07:32]
Where does it create the symlinks? So now I just did stow tmux and previously we had a config symlink here. What should the result be? It's really good to be able to kind of reason about this ahead of time, so that you can really understand the program and how it runs.

[00:07:49]
So we're gonna kinda go with like the scientific method here we're just observing. We're executing and observing cuz I could just tell you exactly what's gonna happen, but I think it's better to learn by watching. Let's just find out, I'm gonna back it up and make your guests right now in your head what you think is gonna happen and see how right you are.

[00:08:07]
So now I'm gonna do it again, I'm gonna do find again. Now it's obviously changed, we still have the test folder. Config is no longer a symlink because there are two files within it, it looks like, and so when I do ls-la on here, you'll see that config is now just a folder.

[00:08:22]
And when I go ls-la in my dot config, you'll see that nvim points to the nvim folder and tmux points to the tmux folder. Now it did not go down and create all those different files. Instead, it points, it went as low as it can in the file path And simply created symlinks there, that's pretty cool, right?

[00:08:42]
We went from a symlink add config to a folder with symlinks that were needed for everything that was already linked at one point. And so for me, this is a pretty exciting experience, so let's try this again. We're gonna do something a little bit different, we got a question either.

[00:08:59]
>> How does it know that it should look at stow-dr for symlink like do you specified this.
>> So yeah, so that was remember that was called in our diagram B or the stow that I've kind of named it, that is where we're executing stow from. So stow goes, okay, from here, I need the stow the nvim folder and where does it put all of its contents?

[00:09:21]
It puts it into the target directory. And so uses the path relative and just puts everything all there for you, so it just does it.
>> So we have to be in the stow-dr to run stow, right?
>> Yes, it doesn't have to be called stow though. It can be called B, it could be called full bar, whatever directory you execute stow from will become the stow there.

[00:09:41]
And where it gets put is one directory up. Now technically, if you go to man stow, you should be able to set up target, right? There is target directories, you can go in here, I'm sure there's terminology and all that in here, but there we go. You can actually set the target directory.

[00:09:56]
So it doesn't need to be in the shape I'm doing it. I'm just doing the default shape, right now, so it feels really obvious what's happening. But you could theoretically set the target and it would behave the exact same way. We would if say your target was just like slash bar.

[00:10:13]
Right now you'd have slash bar dot config, and then two siblings, nvim and tmux.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now