# Builtins, External Commands, Aliases and Functions — Bash / Shell Scripting

Source: https://www.skillbyai.com/en/bash/f-commands

> Tell apart the kinds of commands Bash runs and find their documentation.

## Not every command is a program

When you type a command name, Bash checks, in order: **aliases** (interactive shortcuts, not expanded in scripts by default), **keywords** (`if`, `for`, `[[`), **functions** defined in the current shell, **builtins** (commands implemented inside Bash, such as `cd`, `echo`, `read`, `export`, `test`, `printf`), and finally **external programs** found by searching the `PATH` (`/usr/bin/grep`, `/usr/bin/curl`). Builtins run inside the shell process, which is why `cd` must be a builtin: an external program could not change your shell's directory. `type name` tells you which kind a command is, and `type -a` lists all matches. For documentation, use `help builtin` for builtins (`help read`), `man command` for external programs, and `man bash` for the shell itself. Prefer **`printf`** over `echo` in scripts when output must be exact, because `echo`'s handling of options and backslashes varies between shells.

## Finding out what a command is

`type` answers the question for any name.

```bash
type cd          # cd is a shell builtin
type ls          # often an alias in interactive shells, e.g. ls='ls --color=auto'
type -a printf   # builtin, and also /usr/bin/printf
type if          # if is a shell keyword
command -v jq || echo "jq is not installed"   # portable existence check

help read | head
man 1 printf

# printf is predictable; echo varies
printf '%s has %d items\n' "cart" 3
```

## Check dependencies up front

If a script needs `jq` or `curl`, check with `command -v` at the start and exit with a clear message. Failing halfway through a deployment because a tool is missing is far worse.

**Quiz:** Why must cd be a shell builtin rather than an external program?

- [ ] External programs cannot read directories
- [ ] cd is too small to be a program
- [x] A separate process cannot change the working directory of the parent shell
- [ ] POSIX forbids external cd

*Answer:* A separate process cannot change the working directory of the parent shell. Each process has its own working directory; only the shell itself can change its own.
