Lesson 06 / 20
Navigation Commands
Changing the working directory, reading the listing output column by column, sorting criteria, and accessing a file's complete metadata.
Contents
The previous topic built the project/ tree and placed a script inside it. Before
working on the tree, it must be possible to read it: which files exist, how much
space they take, when they last changed, who owns them.
This lesson decodes the listing output column by column. Reading this output is the verification tool for every operation done in the rest of the course; the result of copying, moving, linking, and changing permissions will always be seen in this same output.
Changing the Working Directory
The cd command changes the working directory and is used in four common forms:
| Command | Effect |
|---|---|
cd path |
Switches to the given directory |
cd |
Returns to the home directory (no argument) |
cd .. |
Goes up one directory |
cd - |
Returns to the previous directory and prints its name |
cd with no argument reads the home directory from the HOME environment variable.
This is a direct use of the environment concept established in the command path
lesson: the home directory is not a value built into the shell, but a setting that
comes from the environment.
Default Listing
The ls command, called with no argument, lists the current directory:
$ cd project $ ls archive docs scripts data
Three behaviors are default: names are sorted, those starting with a dot are not shown, and the output is split into columns according to terminal width.
The third depends on where the command’s output goes:
$ ls archive docs scripts data $ ls | cat archive docs scripts data
The same command writes in columns if its output goes to a terminal, and one name per line if it goes to another program. The reason is that column width is meaningless outside a terminal. This behavior matters for scripts that process the output: trying to parse the column format is unnecessary, because the script already gets one name per line.
To also see names starting with a dot, -a is given:
$ ls -a scripts . .. summary.sh
Long Listing
The -l option gives a one-line metadata summary for every file:
$ ls -l total 16 drwxr-xr-x 2 student student 4096 Jul 26 18:47 archive drwxr-xr-x 2 student student 4096 Jul 26 18:47 docs drwxr-xr-x 2 student student 4096 Jul 26 18:49 scripts drwxr-xr-x 4 student student 4096 Jul 26 18:47 data
The lines consist of seven fields:
1. Type and permissions. The first character is the file type: - regular file,
d directory, l symbolic link, c character device, b block device. The
remaining nine characters are permission bits and will be decoded in detail in the
permissions topic.
2. Link count. The number of directory entries pointing to this file. For
directories this number starts at 2 and each subdirectory adds one: the data
directory’s value of 4 comes from the two subdirectories inside it. What this
number means will be fully explained in the links lesson.
3. Owner user. The file’s owner.
4. Owner group. The group the file belongs to.
5. Size. For regular files, the content size in bytes; for directories, the space taken by the directory entry table — not the total size of the files inside it.
6. Modification time. The moment the content was last changed. If older than six months, the year is shown instead of the time.
7. Name.
The total 16 value in the first line is the number of blocks the listed files
occupy; it is not a file count or a byte total. Block size varies by tool and system,
so this number is not comparable across systems.
The size column is in bytes, and it becomes hard to read for large files:
$ ls -l /usr/bin/bash -rwxr-xr-x 1 root root 1543048 Mar 31 2024 /usr/bin/bash $ ls -lh /usr/bin/bash -rwxr-xr-x 1 root root 1.5M Mar 31 2024 /usr/bin/bash
The -h option converts the size into human-readable units. The conversion rounds;
-h is not used when the exact byte value is needed.
Listing the Directory Itself
When given a directory name, ls lists the directory’s contents. To see the
directory’s own line, -d is needed:
$ ls -ld data drwxr-xr-x 4 student student 4096 Jul 26 18:47 data
This distinction is used constantly to verify results in permission and ownership commands: when a directory’s permissions are changed, the line to check is the directory’s own, not those of the files inside it.
When more than one path is given, the output is divided by headers:
$ ls -li scripts data scripts: total 4 21931 -rwxr-xr-x 1 student student 142 Jul 26 18:49 summary.sh data: total 8 21908 drwxr-xr-x 2 student student 4096 Jul 26 18:47 raw 21909 drwxr-xr-x 2 student student 4096 Jul 26 18:47 processed
The -i option adds a number on the far left: the inode number. This number is
the identity, within the file system, of the structure that holds the file’s
metadata. It is the identity of the file, not of the name — this distinction is the
foundation of the entire links lesson.
Sorting
The default sort is by name. To sort by modification time, -t is used:
$ ls -lt total 16 drwxr-xr-x 2 student student 4096 Jul 26 18:49 scripts drwxr-xr-x 2 student student 4096 Jul 26 18:47 archive drwxr-xr-x 2 student student 4096 Jul 26 18:47 docs drwxr-xr-x 4 student student 4096 Jul 26 18:47 data $ ls -ltr total 16 drwxr-xr-x 4 student student 4096 Jul 26 18:47 data drwxr-xr-x 2 student student 4096 Jul 26 18:47 docs drwxr-xr-x 2 student student 4096 Jul 26 18:47 archive drwxr-xr-x 2 student student 4096 Jul 26 18:49 scripts
-t puts the newest first; -r reverses the order. The -ltr combination puts the
newest last, and it is the most commonly used form for long listings: the most
recently changed file appears at the bottom without needing to scroll.
For files with the same time, the secondary criterion is name; this keeps the output stable for the same input.
Other commonly used sorts are the -S (by size, largest first) and -X (by
extension) options.
The Full Metadata
ls -l is a summary of the metadata. The full set is read with stat:
$ stat scripts/summary.sh File: scripts/summary.sh Size: 142 Blocks: 8 IO Block: 4096 regular file Device: 0,71 Inode: 21931 Links: 1 Access: (0755/-rwxr-xr-x) Uid: ( 1001/ student) Gid: ( 1001/ student) Access: 2026-07-26 18:49:26.461777000 +0000 Modify: 2026-07-26 18:49:26.458777000 +0000 Change: 2026-07-26 18:49:26.460777000 +0000 Birth: 2026-07-26 18:49:26.458777000 +0000
The output reveals three pieces of information hidden in ls -l.
Permissions are given in two forms at once: 0755 and -rwxr-xr-x. These are the
octal and letter representations of the same value; the conversion between them is
the subject of the permission bits lesson.
User and group are shown together with their numeric IDs: 1001/student. The
value the system stores is the number; the name is resolved from a mapping file.
There are three separate timestamps:
- Access — the moment the content was last read
- Modify — the moment the content was last changed;
ls -lshows this value - Change — the moment the metadata last changed; a permission or ownership change updates this, not the content
The third is often confused with the others. When a file’s permissions are changed,
the ls -lt ordering does not change, because the time that changes is Change, not
Modify. This distinction changes the answer to the question “has the file been
touched.”
The Blocks field gives the number of allocated blocks and does not have to be
proportional to Size: a 142-byte file takes up more space on disk because of block
size.
stat is not defined in POSIX, and its output format varies by tool family. The
formatting option is -c in GNU tools and -f in BSD tools; in scripts that need to
be portable, ls output or find criteria are preferred over stat.
Summary
- By default,
lssorts names, skips hidden files, and splits its output into columns if it goes to a terminal. - Long listing gives seven fields: type and permissions, link count, owner, group, size, modification time, name.
- For directories, the size column is the size of the directory entry table; it is not the total of the contents.
-dshows the directory’s own line,-ishows the inode number; the inode number is the identity of the file, not of the name.-tsorts by modification time,-rreverses it;-ltrputs the newest last.- Metadata has three timestamps: access, content modification, and metadata change.
Next Step
The tree can be read now, but it is still empty: there is not a single measurement
file in the raw directory. The next lesson takes up file creation, copying, and
moving; it shows why these three operations have entirely different costs at the file
system level, and under what conditions they silently lose data.
To keep your progress and take notes, Log in
My notes
Log in to take notes.