This chapter discusses the filesystem in depth. In very simple terms, the filesystem is that part of the operating system that takes care of organizing files and directories. Of course, the filesystem does much more than that, and this chapter explores the following aspects of the filesystem:
Various file and directory attributes and how they relate to everyday tasks
Filesystem hierarchy and the location of various useful programs
The concept of supporting multiple filesystems
Managing and maintaining the filesystem
What does the filesystem do for the user ? Besides organizing your data files and useful programs, it also manages configuration information required for the operating system to provide you with a consistent environment every time you restart the computer. It also enforces security and allows you to control access to your files. Processes may read, write, append, delete, move, or rename files and directories. The filesystem defines the rules of the game when such operations are performed.
The shell, combined with a host of other programs, allows you to navigate the filesystem and get your tasks done. Depending on the distribution and installed software, you may also use file managers to navigate the filesystem; in the case of Fedora 2, you can use the Nautilus file manager.
However, one of the most interesting aspects of the filesystem (and one that is not immediately obvious) is that Linux treats almost all devices as files . Hard disks, terminals, printers, and floppy disk drives are all devices ”devices that can be read from and written to (mostly). In fact, with the proc filesystem, Linux goes so far as to provide a filesystem abstraction to running processes. You will see more about this in the The Navigating the Filesystem section. The thing to note is that treating devices as files allows Linux to deal with them in a consistent manner.
Linux supports a wide variety of filesystem types, including Microsoft Windows filesystem types. Some first-time Linux users find it interesting that it is possible to copy a file from a Microsoft Windows filesystem onto a floppy, edit it on a Linux machine, and take it back to Windows. In fact, Linux even allows remote Windows-shared filesystems to be accessed locally using Samba (you ll see more of this in Chapter 9).
To understand the filesystem better, this section starts off with a close examination of an individual file. Examine the following file with a line of data in it:
$ cat >dissectme.txt Innards of this file ^D $ ls l dissectme.txt
Now that we have created our file, let s list it with the ls command:
-rw-r--r-- 1 deepakt users 21 Jan 19 18:40 dissectme.txt
In fact the ls command is your close ally in the exploration of the filesystem. It is a veritable Swiss army knife when it comes to examining the various attributes of a file. By attributes, we mean the various characteristics of the file including its name , date of creation, permissions to access it, and so on. You also need to remember that file and directory names in Linux are case-sensitive ”that is, bluecurve .txt , Bluecurve.txt , and BLUECURVE.txt are all different filenames.
Another curiosity for those coming to Fedora from a Microsoft environment is that filename extensions, such as .txt or .exe do not matter in Fedora 2 (as is the case with most operating systems with a UNIX parentage). Whether a file is executable or not is determined by its permissions. File permissions are explained in some detail in the following sections. In other words, as long as a file has executable permissions, it may be executed as a program; it does not matter if it has a .exe extension or not.
We start off by analyzing the output of the ls command. The first column (that is, the -rw-r--r-- segment) has information about the type of the file and the permissions to access it. The first hyphen (-) symbol indicates that the file is a regular file and not a directory or other type of file. The first character of the ls “l listing always indicates the type of file, to tell you whether it is a regular file, a directory, a FIFO (a mechanism by which programs communicate with each other), a character device (such as a terminal), or a block device (such as a hard disk).
Examples of the various types of files are listed so you understand how they differ from a regular file. In the listing for the /etc directory, you see that the first letter indicating the type of the file is the letter d , confirming that /etc is indeed a directory:
$ ls ld /etc d rwxr-xr-x 59 root root 8192 Jan 19 18:32 /etc
The next two listings initially list one of the first hard disks on the system, /dev/hda in this case. You see the letter b , which indicates that this is a block device. In the listing for the terminal device, /dev/tty , you see that the letter c indicates a character device:
$ ls -l /dev/hda b rw-rw---- 1 root disk 3, 0 Aug 30 16:31 /dev/hda $ ls -l /dev/tty c rw-rw-rw- 1 root root 5, 0 Aug 30 16:31 /dev/tty
A block device performs input and output in blocks of data; for example, when you read a file from the hard disk, data is read in multiples of a block of (say) 4,096 bytes. By contrast, a character device (such as a terminal) reads and writes data one character at a time.
You ll see more about device files in the /dev directory in later sections of this chapter.
In the listing for the bash shell executable in the /bin directory, you see that sh is actually a symbolic link to the Bash shell ( /bin/bash ):
$ ls -l /bin/sh lrwxrwxrwx 1 root root 4 Oct 30 14:46 /bin/sh -> bash
A link is not really a file by itself; rather, it is a pointer to another file. You ll see more about links in the course of the chapter.
The last two listings are rather exotic from a user s perspective because the user rarely (if ever) deals with them directly. Here, we create a FIFO called myfifo , using the mknod command; and then we list it. The letter p indicates that this is a FIFO:
$ mknod myfifo p $ ls -l myfifo prw-r--r-- 1 deepakt users 0 Jan 19 19:09 myfifo $ ls -l /tmp/ssh* /tmp/ssh-XXiVoKic: total 0 s rwxr-xr-x 1 deepakt users 0 Jan 19 18:40 agent.996
A FIFO is a mechanism used by processes to talk to each other; it is therefore known as an inter-process communication mechanism (IPC). FIFO is an acronym for First In, First Out. Programmers, rather than users, deal with FIFOs.
On listing the Secure Shell (SSH) directories in /tmp , you see a file whose listing begins with the letter s . This indicates that the file is a socket , another IPC mechanism that is often used by processes on remote machines to talk to each other.
SSH comprises a set of programs that are intended to provide a secure alternative to UNIX remote access programs that transmit information including passwords in clear-text.
Another command that is useful in checking the type of files is the file command. It does more than just list the type of the file; it is often able to distinguish between files of the same type. That is, it can differentiate between a regular text file and a program file:
$ file /etc /dev/hda /dev/tty /bin/sh /bin/bash dissectme.txt myfifo /tmp/ssh-*/* /etc: directory /dev/hda: block special (3/0) /dev/tty: character special (5/0) /bin/sh: symbolic link to bash /bin/bash: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), stripped dissectme.txt: ASCII text myfifo: fifo (named pipe) /tmp/ssh-XXiVoKic/agent.996: socket
Note the entry for /bin/bash , which indicates that this file is an executable, compiled to execute on an Intel processor. You ll see more about dynamically linked executables in a later section.
Linux treats files as a stream of bytes, without record boundaries; that is, there are no special characters used by the system to distinguish one line from the next. On the other hand, although files on Microsoft Windows operating systems also do not have explicit record boundaries, the operating system uses the convention that text files have a carriage return “line feed pair at the end of lines. The operating system also uses different modes for opening files as text or binary files.
UNIX does not use filename extensions in the way that Windows does. All associations between filenames and extensions are merely based on convention. Typically, UNIX executable files don t have extensions such as .com or .exe .
In examining the /bin/sh file, you noted that it is in fact a link to the file /bin/bash . In other words, /bin/sh is not really a file itself, but anyone executing /bin/sh is actually executing /bin/bash . Actually, Bash is a replacement for the sh shell, and is nearly 100 percent backward compatible with sh.
Let s illustrate the use of links: consider a hypothetical program foo , which has two different modes of operation; in mode one, it copies files, and in mode two, it renames files. One way to switch between the program s modes is to pass it an option; for example, foo “c file1 file2 would create a copy of file1 named file2 . If you pass it the “m option (that is, foo “m file1 file2 ), it would create a copy of file1 named file2 , but would also remove file1 (effectively renaming it).
Another way to switch modes is to create two links to the file foo , one named copy and the other named rename . Now the program foo needs to figure out only the name it was invoked with to switch to the appropriate mode. In other words, if it was invoked with the name copy , foo would copy the file, and if it was invoked with the name rename , it would copy the file and remove the original.
The concept of a link is analogous to that of a shortcut in Microsoft Windows. A link allows you to refer to a file (or directory) by a different name, even from a different directory altogether. This leads to another use of links ”version management of software. Take the case of a program that refers to the libc.so.6 library in the /lib directory. Simply put, a library contains common functions that may be used by several programs:
$ ls -al /lib/libc.so.6 lrwxrwxrwx 1 root root 14 Oct 30 14:45 /lib/libc.so.6 -> libc-2.2.93.so
Here, you can see that libc.so.6 is actually a symbolic link to the actual library libc-2.2.93.so . This means that if the library is upgraded from version 2.2.93 to 2.2.94, for example, the upgrade process removes the link between libc.so.6 and libc-2.2.93.so and creates a new link between libc.so.6 and libc-2.2.94.so . This ensures that the programs referring to libc.so.6 need not be modified every time a library they refer to is changed.
This applies not just to libraries, but also to executable programs. Users typically refer to the program by a link, while system administrators can replace the actual executable with a newer version unbeknownst to the user.
Links come in two varieties: hard links and symbolic links (also known as soft links). Before you learn more about each of these, you need to understand the concept of inodes. Inodes are essentially an indexing mechanisma number by which the operating system refers to a file. The filename is for us mortals; the operating system mostly refers to a file by its inode number.
Linux hard disks are divided into partitions. Partitions allow you to divide the disk into filesystems that have different functionality and are often managed independently of each other. For instance, a system may have a root partition housing all the operating system commands and configuration files and a user partition that houses the directories and files of individual users. You ll see more about partitions in a later section of this chapter.
The inode number is unique only within a disk partition. In other words, it is possible for two files on different partitions (for example, one on the /boot partition and another on the / partition) to have the same inode number. The df command can be used to list the partitions on your system. To see the inode number of a file, you could use the ls command again, this time with the “i option:
$ ls -li /etc total 2012 226972 -rw-r--r-- 1 root root 15228 Aug 5 03:14 a2ps.cfg 226602 -rw-r--r-- 1 root root 2562 Aug 5 03:14 a2ps-site.cfg 226336 -rw-r--r-- 1 root root 47 Jan 19 04:00 adjtime ...
The inode number is listed in the first column. Each file has a unique inode number. While both hard links and symbolic links are used to refer to another file, the real difference is in the inode number:
Hard links have the same inode number as the original file.
Symbolic links have their own unique inode number.
Here are examples of both hard links and symbolic links so you can see how they work:
$ ln dissectme.txt hard.txt $ ln -s dissectme.txt soft.txt
Both hard links and symbolic links can be created using the ln command. While the “s option of the ln command creates a symbolic link, with no options it creates a hard link. Initially, we create a hard link to the file dissectme.txt with the name hard.txt . We then create a symbolic link to the same file, called soft.txt :
$ ls -li dissectme.txt hard.txt soft.txt 131524 -rw-r--r-- 2 deepakt users 21 Jan 19 18:40 dissectme.txt 131524 -rw-r--r-- 2 deepakt users 21 Jan 19 18:40 hard.txt 131528 lrwxrwxrwx 1 deepakt users 13 Jan 19 20:23 soft.txt -> dissectme.txt
When we list all three files with the “i option of ls , you see that inode numbers of the hard link and the inode number of the actual file are the same:
$ cat dissectme.txt hard.txt soft.txt Innards of this file Innards of this file Innards of this file
When we list the contents of the file and the links, you see that the output is just the same, indicating that all three are actually referring to the same file.
Now let s try something else:
$ pwd /home/deepakt $ ln /boot/boot.b boot.b_hard ln: creating hard link `boot.b_hard' to `/boot/boot.b': Invalid cross-device link $ ln -s /boot/boot.b boot.b_soft $ ls -al boot.b_soft lrwxrwxrwx 1 deepakt users 12 Jan 19 20 21 boot.b_soft -> /boot/boot.b
When we attempt to create a hard link to a file on a different partition, the operating system does not allow us to do so because inode numbers are unique only within a partition, and a hard link requires the same inode number as the link target, which may not be possible on a different partition. However, you can successfully create a symbolic link to a file on a different partition.
Links are commonly used for organizing shared directories. For example, a project group may choose to share files in a directory called /var/documents . Users who wish to share documents may choose to leave the documents in any subdirectory under their own home for ease of maintenance. This is how a typical directory structure would look in this case:
$ ls l /var/documents total 0 lrwxrwxrwx 1 deepakt users 22 Feb 23 23:54 deepakt -> /home/deepakt/joe_docs lrwxrwxrwx 1 zora users 18 Feb 23 23:55 zora -> /home/zora/work/blueprints lrwxrwxrwx 1 sarah users 18 Feb 23 23:55 sarah -> /home/sarah/deep/down/mydocs
Members of the group may choose to maintain their documents in any subdirectory under their home directory. They still have the convenience of referring to a colleague s shared documents by accessing /var/documents/ < username >. A new project member, with the username apprentice , would typically execute the following command to add her document directory to this scheme of things:
$ ln s mydocdir /var/documents/apprentice
For this scheme to work, the owner of the /var/documents directory should allow members of the project group write permissions for the /var/documents directory. You ll see more about groups and permissions in the next section.
Every file stored on a Linux system has an owner ”this indicates the creator of the file. Each file also has a group associated with it. A group is essentially a group of users (a number of groups exist on the system by default, including the groups users , administrators , and daemon ). The file /etc/group has a complete list of available groups on the system:
$ cat /etc/group root:x:0:root bin:x:1:root,bin,daemon daemon:x:2:root,bin,daemon sys:x:3:root,bin,adm ... users:x:100:deepakt ntp:x:38: ...
The first column indicates the name of the group.
The second column, indicated by an x character, is the password column.
The third column is the group ID of the group, which is a unique number for the group.
The last column is a list of users who belong to the group.
In this case, the group users has a group ID of 100 and the user deepakt belongs to it.
Take another look at the listing of the dissectme.txt file:
-rw-r--r-- 1 deepakt users 21 Jan 19 18:40 dissectme.txt
In the output here, the third column ( deepakt ) indicates that the owner of this file is a user called deepakt . The fourth column (users) shows that the file belongs to a group called users .
You can assign access control based on group membership. For example, you can arrange for all the members of a certain project to belong to the same group, and set up group access permissions for that group to all the project- related documents on your Linux system. This way, you can allow access to these documents for all users belonging to that group and to no other users. We discuss permissions in the next section.
By default, the file s group is the same as the group that the creator of the file belongs to. However, it is possible to change a file s group so that it is different from that of its owner. To change the ownership of a file, you use the chown command; to change its group, you use the chgrp command.
In the previous ls listing, the -rw-r--r-- part of the output indicates the permissions associated with a file. The permissions block is split into three parts :
The first part indicates the read, write, and execute permissions for the owner.
The second indicates the read, write, and execute permissions for the group.
The last part indicates the read, write, and execute permissions for the rest of the world (that is, users who do not belong to this file s group).
You can use a number of different characters here to reflect permissions:
An r indicates read permission.
A w indicates write permission.
An x indicates execute permission.
A hyphen ( - ) indicates that a particular permission is denied .
Execute permissions for a file do not automatically mean that a file can be executed ”the file also has to be of an executable format (such as an executable binary or a shell script).
Therefore, in the example in the previous section, you see that the owner has permissions to read and write (that is, modify) the file, but no permissions to execute it. Other members of the users group can only read the file, but they cannot modify or execute it. The same permissions also hold for all other users of the system.
For a directory, read, write, and execute have slightly different meanings:
The read permission refers to the ability to list the files and subdirectories contained in that directory.
The write permission refers to the ability to create and remove files and subdirectories within it.
The execute permission refers to the ability to enter the directory using the cd command (in other words, change the current working directory to be this directory).
You can use the chmod command to change permissions for a file by specifying the permissions for the owner, group, and others. An easy way to interpret permissions in the context of directories is to think of directories also as files, the only difference being that these files contain names of files or other directories. Therefore, listing a directory is analogous to reading the contents of a file, and adding or removing contents of a directory is analogous to writing and deleting content from a file.
So what are the default permissions when you create a file? This is controlled by the default file creation mask, which can be set using the umask command.
Let s create a file and a directory and experiment with changing permissions and ownership. First, we ll list the current file mask:
$ umask S u=rwx,g=rw,o=rw
Here the “S option prints out the default file mask in rwx form. This mask allows owners to read, write, and execute files; it allows the group and others read and write permissions, but no execute permissions.
Now, let s modify the file mask:
$ umask u=rwx,g=r,o=r $ umask S u=rwx, g=r,o=r
You do this using the umask command supplying the desired file mask. The new mask allows the owner permission to read, write, and execute, while the group and others have just read permissions. A newly created file reflects the current file mask:
$ mkdir widgets $ ls -ld widgets drwxr--r-- 2 deepakt users 4096 Jan 20 01:05 widgets $ cd widgets $ touch foowidget $ ls -al total 8 drwxr--r-- 2 deepakt users 4096 Jan 20 01:05 . drwx------ 13 deepakt users 4096 Jan 20 01:05 .. -rw-r--r-- 1 deepakt users 0 Jan 20 01:05 foowidget
Here you should notice that (as intended) the foowidget file has just read permissions for the group and others. However, while the file mask reads u=rwx,g=r,o=r , the owner of this file does not have execute permissions because foowidget is interpreted by the shell as a text file, and execute permission does not make sense for text files in general. Shell scripts or other text files of scripting languages such as Perl are therefore treated as text files, but need to be manually assigned execute permissions for them to run. (If you were to compile a program to create an executable, you would notice that execute permission for the owner is enabled. Execute permissions are also enabled by default for the owner when creating a directory because the execute permissions for a directory are necessary to allow users to execute the cd command to enter the directory.)
Now, let s modify the files permissions again:
$ chmod u=rwx,g=rw,o=rw foowidget $ ls -al foowidget -rwxrw-rw- 1 deepakt users 0 Jan 20 01:05 foowidget
This command modifies the permissions of the foowidget file such that the group and others are now allowed to both read and write the file, and the owner is allowed to read, write, and execute it. The file list confirms that the permissions have indeed changed.
Now, let's switch to the root user and change the ownership of the file: $ su Password: # chown nobody:nobody widgets
To change the ownership of the widget directory, you use the chown command. The chown command is restricted to the root user, so you must switch to the root user using the su command and then change the owner and group of the file to nobody and nobody , respectively.
The chown command takes the name of the new owner followed by the filename. Optionally, you can also modify the group by specifying the name of the new group after the owner, separated by a colon ( : ) character. In this case, the owner is nobody and the group is also named nobody . Both the user and group name nobody are used to assign minimum privileges to programs that are often exposed to the external world such as daemon (or server) processes.
Now let s switch back to being a normal user by typing exit in the shell, and try to list the widget directory:
# exit $ ls -al widgets ls: widgets/.: Permission denied ls: widgets/..: Permission denied ls: widgets/foowidget: Permission denied total 0
Now you can check the impact of the changed ownership of the directory. Without the root user s privileges, it s not possible to enter the directory, although the read permission still allows you to see that the file foowidget exists inside the directory.
Finally, let s finish up by trying to remedy this situation. Switch once again to the root user and change the group ownership of the directory to grant permissions for the group, before changing back to a normal user again:
$ ls -ld widgets drwxr--r-- 2 nobody nobody 4096 Jan 20 01:05 widgets/ $ su Password: # chgrp users widgets # chmod g=rwx widgets # exit
The new group ownership and group permissions once again allow you access to the directory:
$ ls -ld widgets drwxrwxr-- 2 nobody users 4096 Jan 20 01:05 widgets $ cd widgets
You ve already seen in this chapter that when a program executes, it needs to have permissions for performing its tasks (see the attempt in the previous section to list the widgets directory). Often non-root users need to perform functions that may be restricted to root users only. This applies not just to the root and non-root user case; in fact, it applies to any user or group the user belongs to that may not have the permission to perform a certain operation.
Fortunately, there is a way to set permissions so that this can happen, without actually elevating the non-privileged user to a privileged status. If a certain command requires root privileges, the superuser can set the setuid execute permissions for this program. Once the setuid bit has been set, it is possible for non-privileged users to execute the program and have it behave as if it were run by root.
The passwd program is a typical example. Regular users can use this program to modify the password they use for logging in. By default on Fedora 2, passwords are encrypted and stored in the /etc/shadow file that can be modified only by the root user. From what you have seen so far, when a user executes the passwd program, the program assumes just the privileges assigned to that user. So how does the passwd program modify this file to update it with the new password? The trick lies in setting the setuid bit:
$ ls al /usr/bin/passwd -r- s --x--x 1 root root 15368 May 28 2002 /usr/bin/passwd
The s indicates the setuid bit for this program. Thus, when the passwd program executes, it assumes the privileges of the root user. Because it is restricted to just updating the /etc/shadow file, there is not much of a risk involved. In simple terms, assigning the setuid bit by a privileged user to a program owned by them indicates that other users can execute the program with the same privileges as the owner. Along the lines of the setuid bit is the setgid bit. When set, the program executes with the privileges of the group it belongs to.
Of course, it is not advisable to assign the setuid bit arbitrarily to programs. System administrators and programmers must carefully review the program before assigning the setuid bit to prevent malicious users from using setuid bit-enabled programs to compromise system security. The setuid and setgid bits can be assigned via the chmod command:
$ chmod u=rws treasure_key.txt (setting the setuid bit) $ chmod g=rws treasure_key.txt (setting the setgid bit)
Any file has three different time attributes associated with it:
mtime is the time at which the file was last modified.
atime is the time at which the file was last accessed.
ctime is the time at which the file s attributes were last changed.
When you list a directory using the ls “l command, the output includes the mtime (the modification timestamp) of each file. The ls command also has a “-time option; this option takes the argument values atime or ctime and displays the other two time attributes accordingly . The touch command (with a filename as the argument) can be used to update a file s mtime and atime .
Let s create a file and perform a few operations on it. After each operation, we ll check the file s mtime , atime , and ctime to determine how they have been affected by the operation.
Let s start by creating a new text file, called time.txt . You can use the cat command to create the file and to put some text into it. Put in as much text as you like, and use Ctrl+D to end the input. Then, use three ls command calls to check the mtime , atime , and ctime (as previously described):
$ cat > time.txt Test of time ^D $ ls -l time.txt; ls -l --time=atime time.txt; ls -l --time=ctime time.txt -rw-r--r-- 1 deepakt users 13 Jan 20 03:49 time.txt -rw-r--r-- 1 deepakt users 13 Jan 20 03:49 time.txt -rw-r--r-- 1 deepakt users 13 Jan 20 03:49 time.txt
You can see that they are all the same. Here, the file was created at 03:49. The file was accessed and modified at that time, and its attributes were all set at that time, so the mtime , atime , and ctime are all the same.
Now, let s modify the content of the time.txt file by overwriting the existing content with some new content. You can use the cat command again, and use Ctrl+D to end the input. Then, look at the mtime , atime , and ctime again:
$ cat > time.txt Sands of time ^D $ ls -l time.txt; ls -l --time=atime time.txt; ls -l --time=ctime time.txt -rw-r--r-- 1 deepakt users 14 Jan 20 03:51 time.txt -rw-r--r-- 1 deepakt users 14 Jan 20 03:49 time.txt -rw-r--r-- 1 deepakt users 14 Jan 20 03:51 time.txt
You can see from this output that the mtime (modification time) attribute has changed, as you d expect because the file has just been modified. More surprisingly, the ctime , that is, the timestamp indicating that attributes have been modified, has also changed because the modification altered the size of the file.
Also, note that the atime didn t change because we have not accessed (that is, read) the contents of the file in the time since we first created it.
Now, let s use cat again, but this time to read and list the contents of the file (note the slightly different usage). Then, look at the mtime , atime , and ctime again:
$ cat time.txt Sands of time $ ls -l time.txt; ls -l --time=atime time.txt; ls -l --time=ctime time.txt -rw-r--r-- 1 deepakt users 14 Jan 20 03:51 time.txt -rw-r--r-- 1 deepakt users 14 Jan 20 03:52 time.txt -rw-r--r-- 1 deepakt users 14 Jan 20 03:51 time.txt
You can see that only the atime has changed, reflecting the fact that we accessed the file but didn t change it (or its attributes) in any way.
Finally, use chmod to change the permissions of the file. Then, look at the mtime , atime , and ctime one more time:
$ chmod u=rwx time.txt $ ls -l time.txt; ls -l --time=atime time.txt; ls -l --time=ctime time.txt -rwxr--r-- 1 deepakt users 14 Jan 20 03:51 time.txt -rwxr--r-- 1 deepakt users 14 Jan 20 03:52 time.txt -rwxr--r-- 1 deepakt users 14 Jan 20 03:53 time.txt
This time, only the ctime has changed because we changed the attributes but did not access or modify the file.
Finally use the touch command to modify a file s timestamps. The touch command can be used to change both the modification and access times of a file or directory:
$ ls -l time.txt; ls -l --time=atime time.txt; ls -l --time=ctime time.txt -rwxr--r-- 1 deepakt users 14 Jan 20 03:51 time.txt -rwxr--r-- 1 deepakt users 14 Jan 20 03:52 time.txt -rwxr--r-- 1 deepakt users 14 Jan 20 03:53 time.txt
The preceding command displays the timestamps ( mtime , atime , and ctime , respectively) of the file. Execute the following commands:
$ touch m time.txt $ ls -l time.txt; ls -l --time=atime time.txt; ls -l --time=ctime time.txt -rwxr--r-- 1 deepakt users 14 Jan 20 03:54 time.txt -rwxr--r-- 1 deepakt users 14 Jan 20 03:52 time.txt -rwxr--r-- 1 deepakt users 14 Jan 20 03:54 time.txt
The modification time has changed since the “m option to the touch command changed the modification time ( atime ). Also notice that, as with the cat > command, the ctime also changed. Pause for a minute and execute the following commands:
$ touch a time.txt $ ls -l time.txt; ls -l --time=atime time.txt; ls -l --time=ctime time.txt -rwxr--r-- 1 deepakt users 14 Jan 20 03:54 time.txt -rwxr--r-- 1 deepakt users 14 Jan 20 03:55 time.txt -rwxr--r-- 1 deepakt users 14 Jan 20 03:55 time.txt
Using the “a option to touch , you can modify the file s access time ( atime ). Consequently, the ctime has also changed.
The difference between using touch and cat (or a text editor) is clearer when it comes to modifying the access time. When changing the atime with touch , the ctime is also modified, whereas it is unchanged when using the cat > command.
The size of a file is indicated in the file listing with the “l option in bytes:
$ ls -al dissectme.txt -rw-r--r-- 1 deepakt users 21 Jan 19 18:40 dissectme.txt To obtain the size of the contents of a directory, you could use the du command. The h option prints the size in a human-readable format (that is, in bytes, kilobytes, megabytes, and so on). The s option summarizes the output rather than list the sizes of each of the files and directories in each of the subdirectories: $ du -sh /home/deepakt/ 153M /home/deepakt
The ls command always displays filenames, regardless of what options you choose. The “F option indicates the various file types with symbols, such as the following:
A slash ( / ) next to a directory
An asterisk ( * ) next to an executable file
A pipe ( ) next to a FIFO
An @ next to a symbolic link
$ ls F a.out* dissectme.txt foo.txt new2 ps_auxww.txt whataboutme.txt@ boot.b_soft@ downloads/ hard.txt new3 ps.txt which.txt crontab.txt env.txt hello.c new4 soft.txt@ widgets/ csh.txt foobar myfifo new5 testcmd.sh*
This command lists a typical directory with all of the different file types in it. Of course, to see the same output, you d have to create these files using the commands described earlier (that is, mkdir for a directory, chmod for setting execute permissions on a file, mknod for a FIFO, and ln for creating a symbolic link).
When the “d option is used with a directory name as the argument, the ls command prints information only about the directory and not about its subdirectories or the files it contains. Another useful option for color terminals is the “ “color option of ls , which lists files of each type with a different color.
Linux does away with the traditional UNIX restriction that filenames cannot have white space characters in them. The following example creates a file called filename with white spaces.txt :
$ cat > "filename with white spaces.txt" This file has white spaces in its name
To read the contents of this file, you can refer to the filename using the slash-space-escape sequence for a white space character:
$ cat filename\ with\ white\ spaces.txt This file has white spaces in its name
In fact, you could interchangeably use double quotes or backslashes irrespective of whether you are creating the file or listing its contents. Also, if you use the bash shell, using the Tab key for command completion automatically adds the slashes to the filename.