Chapter 7. Files and directories

Table of Contents
7.1. Introduction
7.2. The basics
7.3. Permissions
7.4. Extended attributes
7.5. Mounting filesystems

7.1. Introduction

Unix-like operating systems use a hierarchical filesystem to store files and directories. Directories can contain files and other directories, the top directory (/) is named the root directory (not to be confused with the /root directory). Most filesystems also support file links (which provide alternative names for a file) and soft links. Other filesystems can be "connected" to an arbitrary directory. This process is named "mounting", and the directory in which the filesystem is mounted is named the "mount point".

This chapter covers the basic navigation of the filesystem, commands which are used to remove and create directories, filesystem permissions, links and mounting.

7.2. The basics

pwd

pwd(1) is a simple utility which shows the directory you are currently working in. The pwd does not require any parameters. This is an example output of pwd:


$ pwd
/home/danieldk

ls

ls is similar to the dir command in DOS and Windows. ls can be used to display files and directories located in specific directories. Running the ls command without any parameters shows the contents of the current directory:


$ ls
COPYING  CVS  Makefile  README  html  images  pdf  src  tex

Naturally it is also possible to show the contents of other directories. You can do this by specifying the path as a parameter tot the ls command:


$ ls /
bin   cdrom   dev  floppy  initrd  lost+found  opt   root  sys  usr  windows
boot  cdrom1  etc  home    lib     mnt         proc  sbin  tmp  var

A disadvantage of the default output is that it provides little information about files and directories. For example, it is not possible to see whether some entry is a file or directory, what size a file is, or who the owner of the file is. The ls has the "-l" parameter to show more information:


$ ls -l
total 52
-rw-r--r--    1 daniel   daniel      20398 Jul 16 14:28 COPYING
drwxr-xr-x    2 daniel   daniel       4096 Jul 16 14:28 CVS
-rw-r--r--    1 daniel   daniel        768 Jul 16 14:28 Makefile
-rw-r--r--    1 daniel   daniel        408 Jul 16 14:28 README
drwxr-xr-x    3 daniel   daniel       4096 Jul 16 14:28 html
drwxr-xr-x    3 daniel   daniel       4096 Jul 16 14:28 images
drwxr-xr-x    3 daniel   daniel       4096 Jul 16 14:28 pdf
drwxr-xr-x    3 daniel   daniel       4096 Jul 20 00:11 src
drwxr-xr-x    3 daniel   daniel       4096 Jul 16 14:28 tex

cd

Another important command is the cd command. It can be used to change the current working directory:


$ cd /home/danieldk/

With the pwd command you can see it worked:


$ pwd
/home/danieldk

mkdir

As you might have guessed, the mkdir(1) command can be used to create directories. For example:


$ pwd
/home/danieldk
$ mkdir test
$ cd test
$ pwd
/home/danieldk/test

It might happen that you want to create a directory in a parent directory which does not exist yet. For example, if you want to create the test2/hello/ directory, but the test2 directory does not yet exist. In this case you can make both directories with only one mkdir command:


$ mkdir -p test2/hello

cp

Files can be copied with the cp(1) command, the basic syntax is cp source destination. For example, suppose that we have a file named memo which we would like to copy to the writings directory. You can do this with the following command:


$ cp memo writings/

It is also possible to copy a file in the same directory. For example, if we would like to make a new memo based on memo, named memo2, we could execute the following command:


$ cp memo memo2

It is also possible to copy directories recursively, this can be done by adding the -r. The following command copies the memos directory, and all subdirectories, and (sub)files to the writings directory:


$ cp -r memos writings/

mv

The mv(1) command is comparable to cp, but it is used to move files. Suppose that we have the same situation as in the first cp example, but you would rather like to move memo to the writings directory. The following command would do that:


$ mv memo writings/

It is also possible to move directories. But, mv always works recursively. For example, the following command will move the memos directory to the writings directory:


$ mv memos writings/

rm

The rm(1) command is used to remove files and directories. Let's look at a simple example:


$ rm hello.c

This commands removes the file hello.c. Sometimes the rm asks for a confirmation. You can ignore this with the '-f' parameter:


$ rm -f *

This command removes all files in the current directory without asking for confirmation. It is also possible to delete directories or even whole directory trees. rm provides the '-r' parameter to do this. Suppose we want to delete the ogle directory and all subdirectories and files in that directory, this can be done in the following way:


$ rm -r -f ogle/

Many commands allow you to combine parameters. The following example is equivalent to the last one:


$ rm -rf ogle/

7.3. Permissions

A short introduction

Every file in GNU/Linux has permissions. As you might have noticed, file permissions can be shown with the ls -l command:


$ ls -l logo.jpg
-rw-r--r--    1 danieldk users        9253 Dec 23 19:12 logo.jpg

The permissions are shown in the first column. Permissions that can be set are read(r), write(w) and execute(x). These permissions can we set for three classes: owner(u), group(g) and others(o). The permissions are visible in the second to ninth character in the first column. These nine characters are divided in three groups. The first three characters represent the permissions for the owner, the next three characters represent the permissions for the group, finally the last three characters represent the permissions for other users. Thus, the example file shown above can be written to by the owner and can be read by all three classes of users (owner, group and others).

Each GNU/Linux system has many distinct users (a list of users can be found in /etc/passwd), and a user can be a member of certain groups. This kind of user management provides makes it possible to manage detailed permissions for each file. In the example shown above danieldk is the owner of the file and group permissions apply to the group users. In this example groups rights do not differ from the rights of other users.

chown

The chown(1) command is used to set the file owner and to which group group permissions should apply to. Suppose we want to make danieldk the owner of the file logo2.jpg, this can be done with the chown:


$ chown danieldk logo2.jpg

Using the ls we can see that the owner is now danieldk:


$ ls -l logo2.jpg 
-rw-r--r--    1 root     root        9253 Dec 29 11:35 logo2.jpg
$ chown danieldk logo2.jpg
$ ls -l logo2.jpg 
-rw-r--r--    1 danieldk root        9253 Dec 29 11:35 logo2.jpg

But group permissions still apply for the root group. This group can be changed by adding a dot after the owner, followed by the name of the group (in this example the group is nedslackers):


$ chown danieldk.nedslackers logo2.jpg
$ ls -l logo2.jpg
-rw-r--r--    1 danieldk nedslackers        9253 Dec 29 11:35 logo2.jpg

It is also possible to change ownership recursively, this can be done with the recursive (-R) parameter:


$ chown -R danieldk.users oggs/

chmod

File permissions can be manipulated using the chmod(1) command. The most basic syntax of chmod is chmod [u,g,o][+/-][r,w,x] filename. The first parameter consists of the following elements: 1. which classes this manipulation permission applies to, 2. if the permissions should be added (+) or removed (-), and 3. which permissions should be manipulated. Suppose we want to make the file memo writable for the owner of the file and the groups for which the group permissions apply. This can be done with the following command:


$ chmod ug+w memo

As you can see below the memo is now writable for the file owner and group:


$ ls -l notes 
-r--r--r--    1 daniel   users          12 Mar  9 16:28 memo 
bash-2.05b$ chmod ug+w memo
bash-2.05b$ ls -l notes 
-rw-rw-r--    1 daniel   users          12 Mar  9 16:28 momo 

Just like the chown command it is also possible to do recursive (-R) operations. In the following example the secret/, including subdirectories and files in this directory, is made unreadable for the group set for this directory and other users:


$ chmod -R go-r secret/

7.4. Extended attributes

7.4.1. Introduction

Extended attributes (EAs) are relatively new on GNU/Linux. Extended attributes are a special kind of values that are associated with a file or directory. EAs provide the means to add extra attributes besides the common attributes (modification time, traditional file permissions, etc.). For example, one could add the attribute "Photographer" to a collection of JPEG files. Extended attributes are not physically stored in the file, but as meta-data in the filesystem.

Extended attributes are only supported by 2.6.x and newer 2.4.x kernels. Besides that they are not supported on all filesystems, the commonly used Ext2, Ext3 and XFS filesystems do support extended attributes.

7.4.2. Installing the necessary utilities

The extended attribute software is available from the the Debian archives as the attr package. You can install it through your favorite package manager, or APT:


# apt-get install attr

7.4.3. Showing extended attributes

Extended attributes can be queried using the getfattr command. Just using getfattr with a file as a parameter will show the attributes that are known for that particular file, without the values set for the attributes. For example:


$ getfattr note.txt 
# file: note.txt
user.Author

This file has one extended attribute, "user.Author". An attribute has the following form: "namespace.attribute". There are four defined namespaces: "security", "system", "trusted", and "user". The role of these namespaces are described in the attr(5) manual page. The "user" namespace is of particular interest to us, because this namespace is used to assign arbitrary attributes to files.

The values associated with an attribute can be shown using the "-d" (dump) parameter. For example:


$ getfattr -d note.txt 
# file: note.txt
user.Author="Daniel"

In this example the attribute "user.Author" has the value "Daniel" for the file note.txt.

7.4.4. Setting extended attributes

Attributes are set with the setfattr command. An attribute can be added to a file using the "-n" (name) parameter, be sure to specify the namespace and the attribute name, for example:


$ setfattr -n user.Author note2.txt

The value of the attribute can be set using the "-v" (value) parameter:


$ setfattr -n user.Author -v Mike note2.txt

But it is also possible to add an attribute and setting its value in one run, by specifying both the "-n" and "-v" parameters. For example, the following command adds the MD5 sum of the file as an extended attribute:


$ setfattr -n user.MD5 -v `md5sum note2.txt` note2.txt
$ getfattr -d note2.txt
# file: note2.txt
user.Author="Mike"
user.MD5="78be7a3148027ae7a897aad95e7d9c58"

7.5. Mounting filesystems

7.5.1. Introduction

Like most Unices Linux uses a technique named "mounting" to access filesystems. Mounting means that a filesystem is connected to a directory in the root filesystem. One could for example mount a CD-ROM drive to the /cdrom directory. Linux supports many kinds of filesystems, like Ext2, Ext3, ReiserFS, JFS, XFS, ISO9660 (used for CD-ROMs), UDF (used on some DVDs) and DOS/Windows filesystems, like FAT, FAT32 and NTFS. These filesystems can reside on many kinds of media, for example hard drives, CD-ROMs and Flash drives. This section explains how filesystems can be mounted and unmounted.

7.5.2. mount

The mount(8) is used to mount filesystems. The basic syntax is: "mount /dev/devname /mountpoint". The device name can be any block device, like hard disks or CD-ROM drives. The mount point can be an arbitrary point in the root filesystem. Let's look at an example:


# mount /dev/cdrom /cdrom

This mounts the /dev/cdrom on the /cdrom mountpoint. The /dev/cdrom device name is normally a link to the real CD-ROM device name (for example, /dev/hdc). As you can see, the concept is actually very simple, it just takes some time to learn the device names ;). Sometimes it is necessary to specify which kind of filesystem you are trying to mount. The filesystem type can be specified by adding the "-t" parameter:


# mount -t vfat /dev/sda1 /flash

This mounts the vfat filesystem on /dev/sda1 to /flash.

7.5.3. umount

The umount(1) command is used to unmount filesystems. umount accepts two kinds of parameters, mount points or devices. For example:


# umount /cdrom
# umount /dev/sda1

The first command unmounts the filesystem that was mounted on /cdrom, the second commands unmounts the filesystem on /dev/sda1.

7.5.4. The fstab file

The GNU/Linux system has a special file, /etc/fstab, that specifies which filesystems should be mounted during the system boot. Let's look at an example:


/dev/hda10       swap             swap        defaults         0   0
/dev/hda5        /                xfs         defaults         1   1
/dev/hda6        /var             xfs         defaults         1   2
/dev/hda7        /tmp             xfs         defaults         1   2
/dev/hda8        /home            xfs         defaults         1   2
/dev/hda9        /usr             xfs         defaults         1   2
/dev/cdrom       /mnt/cdrom       iso9660     noauto,owner,ro  0   0
/dev/fd0         /mnt/floppy      auto        noauto,owner     0   0
devpts           /dev/pts         devpts      gid=5,mode=620   0   0
proc             /proc            proc        defaults         0   0

As you can see each entry in the fstab file has five entries: fs_spec, fs_file, fs_vfstype, fs_mntops, fs_freq, and fs_passno. We are now going to look at each entry.

7.5.4.1. fs_spec

The fs_spec option specifies the block device, or remote filesystem that should be mounted. As you can see in the example several /dev/hda partitions are specified, as well as the CD-ROM drive and floppy drive. When NFS volumes are mounted an IP address and directory can be specified, for example: 192.168.1.10:/exports/data.

7.5.4.2. fs_file

fs_file specifies the mount point. This can be an arbitrary directory in the filesystem.

7.5.4.3. fs_vfstype

This option specifies what kind of filesystem the entry represents. For example this can be: ext2, ext3, reiserfs, xfs, nfs, vfat, or ntfs.

7.5.4.4. fs_mntops

The fs_mntops option specifies which parameters should be used for mounting the filesystem. The mount(8) manual page has an extensive description of the available options. These are the most interesting options:

  • noauto: filesystems that are listed in /etc/fstab are normally mounted automatically. When the "noauto" option is specified, the filesystem will not be mounted during the system boot, but only after issuing a mount command. When mounting such filesystem, only the mount point or device name has to be specified, for example: mount /mnt/cdrom

  • user: adding the "user" option will allow normal users to mount the filesystem (normally only the superuser is allowed to mount filesystems).

  • owner: the "owner" option will allow the owner of the specified device to mount the specified device. You can see the owner of a device using ls, e.g. ls -l /dev/cdrom.

  • noexec: with this option enabled users can not run files from the mounted filesystem. This can be used to provide more security.

  • nosuid: this option is comparable to the "noexec" option. With "nosuid" enabled SUID bits on files on the filesystem will not be allowed. SUID is used for certain binaries to provide a normal user to do something privileged. This is certainly a security threat, so this option should really be used for removable media, etc. A normal user mount will force the nosuid option, but a mount by the superuser will not!

  • unhide: this option is only relevant for normal CD-ROMs with the ISO9660 filesystem. If "unhide" is specified hidden files will also be visible.

7.5.4.5. fs_freq

If the "fs_freq" is set to 1 or higher, it specifies after how many days a filesystem dump (backup) has to be made. This option is only used when dump(8) is set up correctly to handle this.

7.5.4.6. fs_passno

This field us used by fsck(8) to determine the order in which filesystems are checked during the system boot.