Command Line Basics: How the Shell, bash, and Command Execution Work

Command Line Basics: How the Shell, bash, and Command Execution Work

What You Will Achieve

  • Explain what a shell is and how bash interprets and executes commands
  • Distinguish command type and real path accurately with type / which
  • Understand PATH resolution order and diagnose "command not found"
  • Use single / double / backslash quoting correctly
  • Apply command history and history expansion in real work

This is the core of LPIC-1 objective 103.1 "Work on the command line". Understanding the shell's execution model is the foundation for all later text processing and process management.

Shell and Command Execution Decision Flow

A shell is a program that interprets the line you type and launches commands. bash (Bourne-Again Shell) is the default on most distributions. When you type a command, bash first expands aliases (check with alias, e.g. llls -l) at the command-line parsing stage. An alias is not part of the search order; it is substituted earlier, in a separate stage before the search. bash then resolves the resulting word in the following order.

Order Type Check command Example
1 Shell function declare -F User-defined function
2 Shell builtin type -a cmd cd / echo / pwd
3 External on PATH which cmd /bin/ls

Without this order you cannot explain "is echo the builtin or /bin/echo" or why time behaves specially.

Steps

Step 1: Check the shell type and version

echo $SHELL
bash --version
/bin/bash
GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)

$SHELL is the login shell. The currently running interactive shell is shown by $0 or ps -p $$.

Step 2: Determine the command type

type cd
type ls
type -a echo
cd is a shell builtin
ls is aliased to `ls --color=auto'
echo is a shell builtin
echo is /usr/bin/echo

type is a bash builtin and reflects the resolution order itself. -a shows every candidate with the same name. If you only need the external path, use which.

which cp
/usr/bin/cp

which returns only the first match on PATH. It does not detect builtins or aliases, so use type for type identification.

Step 3: Understand PATH resolution order

echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

PATH is a colon-separated directory list. bash searches external commands left to right and runs the first executable found. When the same command exists in multiple directories, the one earlier in PATH wins.

Step 4: Control metacharacters with quoting

name=world
echo "hello $name"
echo 'hello $name'
echo hello \$name
hello world
hello $name
hello $name

Double quotes (") perform variable expansion and command substitution but suppress word splitting and globbing. Single quotes (') suppress all expansion and treat the content literally. A backslash (\) escapes the single character that follows.

Step 5: Use command history

history 5
!!
!123
!grep
  120  cd /var/log
  121  ls -l
  122  grep error syslog
  123  tail -f syslog
  124  history 5

!! re-runs the previous command, !n re-runs history number n, and !string re-runs the most recent command starting with string. Ctrl+r provides incremental history search.

Why This Order

bash's command search order is strictly "function → builtin → external (PATH)"; an alias is not part of this search order but is expanded earlier, at the command-line parsing stage (before the search). The design is so that user definitions and internal processing take precedence over external commands. For example echo exists both as a builtin and /usr/bin/echo, and preferring the builtin avoids the cost of spawning a subprocess. time behaves "not like a command" because it is a reserved word (keyword) that measures an entire pipeline and is interpreted before builtins.

PATH front-priority lets you place a custom-built command in /usr/local/bin and have it take precedence over the system standard. Conversely, an unintended same-name command resolved first becomes an incident, so always confirm all candidates with type -a when the type is unknown.

Troubleshooting

Symptom: command not found appears

Cause: The command is not on PATH, or PATH itself is broken

Check:

echo $PATH
type -a cmdname

Fix: Locate the executable with find / -name cmdname -type f 2>/dev/null and add its directory to PATH. If PATH is nearly empty, suspect a misconfiguration in .bashrc / .bash_profile.

Symptom: A variable is not expanded

Cause: It is wrapped in single quotes

Check:

echo '$HOME'
echo "$HOME"

Fix: Use double quotes where variable expansion is required. Use single quotes or \$ only when you want a literal $.

Symptom: which and type disagree

Cause: which only sees external commands while type reflects the resolution order including aliases and builtins

Check:

type -a ls
which ls

Fix: Always trust type to know how a command is actually executed. Limit which to obtaining an executable path inside scripts.

Completion Checklist

  • [ ] Confirmed the shell environment with echo $SHELL and bash --version
  • [ ] Checked the type of key commands with type -a
  • [ ] Verified the search order with echo $PATH
  • [ ] Verified single / double quote expansion differences on a real machine
  • [ ] Tried history and history expansion (!! / !n)

Summary

Scenario Command Purpose
Type check type -a cmd Distinguish alias/function/builtin/external
Real path which cmd Get executable path on PATH
Path check echo $PATH Understand command search order
Re-run !! / !n Re-run previous/numbered command
Suppress expansion '...' / \ Treat metacharacters literally

Shell resolution order and quoting behavior are the foundation throughout LPIC-1. Next, move to shell environment configuration to connect the concepts.

Next Reading