Member preview

What happens when you type `ls *.c` into your shell

(Note: This post assumes you are familiar with the general concepts of files, directories, filename extensions, how there are different kinds of programming languages, and how to use the terminal. My screen captures differs from the conventional terminal interface as I am using iTerm2.)

If you’re happy, and you know it, what is the Unix command to list all the files in your current directory? Clap with me now:


It’s short for the word list [ls] (it’s a great practice to think about any command’s function and why the language’s inventor would name the command such). So by typing in [ls] and hitting [Enter], you get:

The beauty of Unix commands is you can refine what they do (their functionality) using Options or Wildcards. In this case, we want to list (output) all files and directories (within our current directory) with the filename extension “.c” by using the “ * ” [asterisk] wildcard.

Wait what huh what gahgah googoo blahblahblah?

My bad. Alright, so, as you can see in that [ls] picture up there, we have 8 files total:

File one: 0-alias
File two: 1.c
File three: 1-hello_you
File four: 2.c
File five: 2-path
File six: 3-paths
File seven: 4-global_variables
File eight:

…but only 2 of them have the filename extension “.c”

File two: 1.c
File four: 2.c

What we want to do is to only list [ls] these particular “.c” files. To do this, we refine the list (output) using [ls] list command + [*] wildcard + [.c] filename extension or, all together now:

ls *.c

By inputting this command, we will get, what kind of output? You got it!

We only get the files with the filename extensions “.c” (which are C programming language files).

That’s what happens on the surface, but what happens under the hood? What underlies the seeming magic?

The input is broken up into words and operators.

The shell reads the input from the command line, dividing up the input (‘ls *.c’) into words and operators.

Alias expansions happens

The shell identifies the first command, and checks if there are aliases for the specified command. What is an alias? An alias is a command in various command line interpreters (shells) which enables a replacement of a word by another string. It is mainly used for abbreviating a system command.

If an alias is found, the shell checks if there are any aliases for that alias.

Shell expansion happens

An expansion is when a symbol or character expands into larger text, files or general output. The expansion finding all files and directories is ‘*’. Writing a string or (even) another expansion, before or after the ‘*’ will find all files that end or begin with the string. In this case, ‘*.c’ will output all files ending with ‘.c’

Commands executed

The shell searches for the command in the built-in functions — if it’s not there, it will fine the $PATH, an environmental variable specifying where the executable programs are located. Once found, the command is executed. The command in this case, ls will list all the .c files.

Shell waits for the command to complete, then after its done, exits the command and Bash prints the prompt again.

Print command line (PS1) and $

The environment variable PS1 is used for the format of the prompt — is the default interaction prompt for the command line: it displays the username, hostname, and full path name of the user directory. The last step after running the ‘ls * .c’ command is printing the command line prompt (PS1).

Reference (damn near verbatim because she said it perfectly):

The magic of ‘ls * .c’ by Jennie Z Chu