how the terminal works: command line input

I am a Software Engineering Student at Holberton School, San Francisco | contact me or follow me.


:do you ever wonder how a computer works?

As a beginner software engineering student at Holberton School, we are being taught to use the terminal command line to use the functions of a computer. In this post I will explain a very basic concept of what happens with a computer when a user types input. In my work so far and in the ways that I explain a computer system, I will be referring to the bash shell program in Mac OS terminal using ubuntu and GNU linux (click the links for wikipedia references on those concepts).

Additionally, to help with my explanation, I’ll use the input command ls *.c as an example of many of the concepts of how terminal and a computer work. This is how that command might look in your terminal:

USER@computerNAME: ~/$ ls *.c


To learn about commands from the manuals in terminal input ~/$ man yourcommand; an excert from the manual on ls states:

NAME ls -- list directory contents


DESCRIPTION List information about the FILEs.

In addition to this instruction on what the command does, there are over 30 different options that can be combined with ls, yikes! I'm not going to discuss what all the options mean, because for the purpose of this discussion, the only important thing to know is that ls lists directory contents including files and other directories. Since there is only one specifications in this example *.c, the command will list the contents of the current directory. The specification of what is listed is based on the *.c.

The asterisk “ * ” is being implemented as a wildcard. The “ * ” wildcard is used to represent any number of characters from 0+(zero plus). In this example, we are listing out directory contents. Therefore the addition of the * means: list all the contents with any number of characters in the name. So, if the terminal input command terminated with ls *, then this would list out all contents of the current directory and all subdirectories, including directories, excluding hidden files.

However, the asterisk is followed by .c, which means that the string of characters being listed must terminate in “.c” to qualify as content to be listed. The ".c" extension is used to specify files written in the C Programming Language. Additionally, when the ".c" extension is added, the terminal shell program no longer returns results from all subdirectories, only the current directory, and excluding hidden files. If there are no ".c" files, then the line: "ls: cannot access *.c: No such file or directory" is listed in the terminal. If there are ".c" files in the current directory, then those files will be listed with no other additional information about them (this is because no "ls -options" were specified).

What happens after hitting keys on your keyboard?

With this information, you can see how a command is input, and the output from the computer is to return a list of all files and directories, in the current directory, excluding hidden files, whose names terminate with “.c” extension.

Nevertheless, what is really happening with a computer with these and the thousands of other inputs that a user could put into terminal?

GNU Linux coreutils

As soon as a user inputs a message into terminal by clicking ‘enter’ or ‘return’, the command line program language, (Bash or Bourne again shell in my examples) begins to implement various steps. First Bash checks for aliases in your bash profile, which could be written in the file .bashrc.profile or .bash_profile; aliases could also be cached as temporary aliases. Aliases are short codes for other codes, which are executable files. So, Bash checks your aliases to see if your input command is an alias, and the command is an alias, bash then searches for the command of the alias.

Example of an alias: alias ll='ls -alF’. This is one line from my .bashrc file.

Some commands are “built-in” to bash shell program. To see a list of these commands type man builtins or compgen -b; one such commands is “cd” for change directory. “ls” happens to not be a part of the built-in commands. Therefore the bash shell program begins to search for what your instructions mean by following a path and searching the files in that path for the instructions to your instructions.

The path the terminal follows where executable programs are located is called the: $PATHs (‘$’ meaning that it is an environmental variable).

Example of the $PATH from my vagrant ssh virtual box with ubuntu: /usr/local/sbin:usr/local/bin:/usr/sbin:/usr/bin:sbin:/bin:/usr/games:/usr/local/games

So, in our example, the bash shell performs a search through all the above directories, looking for the instructions, which happen to files, for the instructions ls *.c that the user implemented into the command line interface. Bash uses the stat() system call to check for the existence of an executable command: 'ls' in each directory in the path. When bash finds ls (on my vagrant installation of ubuntu and bash, “ls” is located in: /bin/ls) it calls execve() to execute the command on the script or code block that it found. The file on my computer called “ls”, is an executable file written in binary and compiled from a C language file, and so we cannot easily look at it to understand the code (or instructions) for this file. For more on compiling C programming languages, see my other blog post: Computer Compilers: brief introduction. For the purpose of this blog post, “ls” is an executable file that does what I explained in the beginning of this blog post. After the files are listed from the ls command, the command prompt returns to wait for another input from the user.

The original ls.c file that contains the code was compiled to to create ls, can be accesses on the GNU Linux coreutils webpage. This is one of the great perks of open source software from the GNU Library! The file has over 5000 lines of code in it, and so therefore I will not explain the entire meaning of the file. Essentially, this file give instructions to the silicon and metal of the computer processor, to begin to carry out the instructions that will eventually return the output that the user intended. In the ls *.c case, the computer will return a list of all the files in the current directory with .c extensions, which will be printed onto the bash terminal output lines.

Here is a brief excerpt of the code in C programming language from the file ls.c from the GNU Linux foreutils library on the executable file “ls.” What do you think this code does? Hint: I referenced this part of the code in another section of this article!

usage (int status)
  if (status != EXIT_SUCCESS)
    emit_try_help ();
      printf (_("Usage: %s [OPTION]... [FILE]...n"), program_name);
      fputs (_("
List information about the FILEs (the current directory by default).n
Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.n
"), stdout);

      emit_mandatory_arg_note ();

      fputs (_("
  -a, --all                  do not ignore entries starting with .n
  -A, --almost-all           do not list implied . and ..n
      --author               with -l, print the author of each filen
  -b, --escape               print C-style escapes for nongraphic charactersn
"), stdout);
      fputs (_("
Posted in bash, code, command line and tagged , , , .