Skip to content
academia.sh

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 -l shows 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, ls sorts 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.
  • -d shows the directory’s own line, -i shows the inode number; the inode number is the identity of the file, not of the name.
  • -t sorts by modification time, -r reverses it; -ltr puts 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.

Start typing to search.

↑↓ Esc navigate · open · close