This is a LinuxChix course page. This and the other courses pages are yet to be ported to the new LinuxChix website. Please feel free to browse the course in the meantime.

We appreciate your patience.

The UNIX Filesystem: Lesson 2

Introduction

This lesson makes a small digression into areas that some readers will know about and some won't. Before learning any more about filesystems, it is important to know about some basic concepts. About half the lesson will be devoted to these ("Background information"). After that, we can start getting some practical work done, and learn how to mount and unmount sections of the filesystem. This will come in lesson 3.

Relative paths

I'll be assuming you're familiar with relative paths. Very briefly:

Every process has a working directory. This is the directory the process is running "inside". To see the current working directory of your shell, type pwd, which stands for Print Working Directory. Here's what happens when I use it:

The shell

What is a shell? A shell is a program just like any other - there is nothing particularly mystical about it. You can interact with a shell by typing a command into it. It will run this command, and, when it is finished, present the prompt (in my case, meredydd@rhodium:~$) and wait for another instruction.

Which shell is started when you log in is determined by your user's entry in /etc/passwd. On Linux systems, the normal shell is /bin/bash. The shell specified in /etc/passwd can be any program whatsoever - a good (but not watertight) method of restricting what a user can do on a system is to set their shell to something useless (such as /bin/false, a program which just returns an error code), thereby disabling shell access. Alternatively, you could put in a program or shell script which offers a menu, limiting their choice of programs to run (Cambridge University's hermes mail server does just that).

If you want to try out a different shell to the one you're using, you can start it just like any other program. For example, to try out the C shell, tcsh, type tcsh at your prompt. Your current shell (for example, bash) will start the C shell, and wait for it to finish. Once you type exit, the shell will exit, and your original shell will take up the baton once again.

The shell prompt is very configurable. You'll probably notice that my use of pwd here isn't necessary, as my prompt tells me my current working directory at all times. You'll also notice the abbreviation ~ - this symbol is expanded by the shell into the path of my home directory. So, instead of typing cd /home/meredydd/web/, I can just type cd ~/web/. Much nicer.

The important thing here is the third line. I change directory into /usr/, and then into bin/. The net effect is therefore to put me in /usr/bin. This is called a relative path - it depends on the current working directory. If I had executed cd bin/ when my working directory was /, I would end up in /bin/ instead.

Another thing I demonstrate is the ../ directory. In any directory, ../ refers to the directory above it (/ is an exception - its ../ directory refers to itself).

Likewise, ./ refers to the current directory. Why is this useful? Well, it's not that frequently used. The main application is forcing a shell to run something in the local directory. For example, if I just typed somecommand into my shell, the shell would search all the directories in the PATH environment variable for an executable file called somecommand. If you type ./somecommand, the shell sees that it's a relative path, and doesn't search for the program. Instead, it just runs it from ./ - the current working directory.

Permissions

Each process has an identity attached to it. For each process, the operating system kernel stores a UID - User ID. When you log in, the UID of your shell (and, therefore, all its child processes such as text editors, web browsers, and so on) is the number given to your username in the file /etc/passwd. The process also carries one or more GIDs - Group IDs. When you log in, your shell (and all its descendants) acquire the GIDs of all the groups of which /etc/group lists you as a member.

Each file or directory also has a UID, and one GID. It also has three sorts of permission - read, write, and execute. There are three versions of these permissions - one each for "user", "group", and "other".

Let's see what that looks like:

meredydd@rhodium:~$ ls -l snapshot.tgz
-rw-r--r--    1 meredydd users       10007 Jun 20 00:08 snapshot.tgz
meredydd@rhodium:~$

If we look at the output of ls -l, we see that the file snapshot.tgz is owned by the UID which corresponds to the user "meredydd" in /etc/passwd, and the GID which corresponse to "users" in /etc/group.

What's more, it has a permission set of rw-r--r-- (ignore the first dash - that's a 'd' if you're looking at a directory). This means that the owner (me) has read and write access (but not execute), the group ("users") has read access but not write or execute, and the same goes for everyone else.

OK, that's a whistle-stop tour of file permissions. The one remaining topic is how this applies to directories. With directories, one needs execute permission to access anything in that directory, read permission to list the files in the directory, and write permission to create files there.

Symbolic links

Symbolic links, sometimes called "soft links", are another topic which tends to confuse migrating users from other operating systems. The concept is somewhat akin to a shortcut - a symbolic link acts just like its target.

The easiest way to demonstrate symbolic links is to make one and look at how they behave. You can make one with the ln command, passing it the -s option.

You can follow through this example yourself - all you need is a directory called web/, and a directory called backups, and to change every reference to /home/meredydd to your own home directory.

Let's walk through that, shall we?

  1. First, I show the contents of my home directory, and demonstrate that my backups/ folder has nothing in it.

  2. Then comes the real magic. Breaking down that command:
    ln -s /home/meredydd/web/ backups/
    Make a link Make it symbolic Target path Where to put the link


  3. I then list the contents of the backups/ folder, to show that it does indeed contain a link to /home/meredydd/web/, called "web".

  4. Now, to all intents and purposes, the path backups/web/ acts just like web/. It's not a copy - if you change something in one, it will be reflected in the other. This is a very useful - the example here is one I use myself. I have a backups/ folder. In it, I place symbolic links to everything I want backed up on a regular basis. That way, I can just run a script which copies everything in that directory to my backup server - it will follow the links, and back up all my work.

Worth noting
Symlinks are not quite perfect. Remember the ../ directory I discussed a little while ago? Well, directories that are the targets of symbolic links are no exception - they have one too. They are not, however, exactly what you might expect.

If you look at the directory backups/code/../ in the example we just worked through together, you'll see that it's not backups/ at all - it's the home directory, the parent of the target!

If you think about it, it does make sense - a directory's ../ path is the same, no matter whether you got there from its parent directory or by following a symlink. But it's worthwhile being a little wary of using ../ when symlinks are involved.

It's not only directories which can have symbolic links made to them. Ordinary files, and even special files like devices (again, we'll come to this in a few lessons' time), can be linked to just like anything else. It's also worth noting that because of the unified filesystem I talked about in lesson 1, symbolic links don't care about where the files they're linking to are stored. You can create a symlink on your hard drive to a file on your floppy drive, and the system won't even blink.

One more important point, and one you should never forget: Symbolic links are relative!. I can't tell you how many times this one has caught me out. The path you give as a target to the ln command will be relative to the directory in which the link is created.

So, for example, if I had executed the command:

ln -s web/ backups/

...it would have created the link, but then failed horribly (with a "file not found" error) when I tried to follow it. The reason? The path "web/" would have been evaluated relative to the directory where the link is (/home/meredydd/backups/), not the directory we were in when we created the link (/home/meredydd/).

A guaranteed safe method of avoiding this is to use absolute paths - paths beginning with a /, which are the same wherever they are evaluated from. For example, /usr/bin/ is an absolute path, and bin/ is a relative path which only refers to the same directory if it's evaluated in /usr.

Further reading

A good (if somewhat technical) explanation of links is available on the Linux man page for the ln command. "man ln" should do it.

Exercises

Follow through the example here. Try it again, with different directories. Play around. See what happens when you create circular links (links which point to their own parent directory, or even to themselves). As always, tell me how you get on, and ask me if you have any questions at all.

Next Lesson

Next lesson will introduce us to some of the details of mounting and unmounting sections of the filesystem, including devices, filesystem drivers, and some actual concrete exercises for once.