Bash Builtins Versus External Commands
A builtin is a command built into the shell itself. An external command is a separate program found through PATH, and it cannot change the shell's state.
type -t tells builtin from external
echo and cd are builtins. grep and sort are external programs, shown as file.
type -t echo
type -t cd
type -t grep
type -t sortDisabling a builtin reveals the external program
echo starts as a builtin. With the builtin disabled, the shell reports the external echo. Re-enabling it restores the builtin.
type -t echo
enable -n echo
type -t echo
enable echo
type -t echoA counter proves the external route's cost
The builtin loop and one grep call agree on 2 matches. The counter proves the external route cost one process start.
printf 'apple\nbanana\napple\n' > data.txt
builtin_matches=0
while IFS= read -r line; do
case "$line" in *apple*) builtin_matches=$((builtin_matches+1));; esac
done < data.txt
external_calls=0
count_with_grep() {
external_calls=$((external_calls+1))
echo "external matches: $(grep -c "$1" data.txt)"
}
echo "builtin matches: $builtin_matches"
count_with_grep apple
echo "external calls: $external_calls"Example
for cmd in echo cd grep sort; do
kind=$(type -t "$cmd")
echo "$cmd: $kind"
doneKey points
- type -t: prints builtin for a builtin and file for an external command, with no path.
- cd is a builtin: only a builtin can change the shell's own working directory.
- command: runs a command while skipping functions; builtin forces a builtin.
- enable -n: disables a builtin, so the shell falls back to the external program of the same name.
- External cost: each external command starts a new process; builtins run inside the shell.
- Counting proof: wrap an external call in a function that counts, and compare counts, not timings.
- Same result check: a builtin loop and one external call can agree on a count.
In this example, the loop walks four command names. For each name, type -t reports its kind. The loop prints builtin for echo and cd, and file for grep and sort.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
Why can cd change the shell's directory but an external program cannot?