← back to latest

Find out what a command actually is before you run it

type -a grep

anatomy

type
A shell built-in that tells you how the shell resolves a command name. Unlike which, it knows about aliases, functions, and built-ins, not only files on disk.
-a
Show all matches, not only the first one. If grep is both an alias and a binary, you see both. Without this flag the shell stops at the first match, which is the one it would actually run.
grep
The command name to look up. Replace with any command you want to inspect.

Sample output

grep is aliased to `grep --color=auto'
grep is /usr/bin/grep

Two matches. The shell runs the alias first, which wraps the real binary with --color=auto. If you did not know the alias existed, you might wonder why piping grep output into another tool includes ANSI color codes that break parsing.

When you would reach for it

A command behaves differently on your machine than on a colleague’s, or differently in a script than in your interactive shell. An alias or function is shadowing a binary and you cannot figure out why the flags you passed are being ignored. You installed a newer version of a tool and want to confirm the shell is picking up the right one.

Gotchas

  • type is a shell built-in, so it sees aliases and functions defined in your current session. If you run it inside a script, it will not see the aliases from your .bashrc because non-interactive shells do not source that file by default.
  • which is not equivalent. On most systems, which is an external binary that only searches PATH. It does not know about aliases, functions, or built-ins. type is almost always what you actually want.
  • In zsh, type is an alias for whence -v. The output wording differs from bash (“grep is an alias for grep –color=auto” versus “grep is aliased to `grep –color=auto’”), but the information is the same.
  • If type -a shows multiple file paths, the first one wins. This is how a Homebrew-installed GNU tool can shadow a BSD built-in on macOS, or vice versa.

Variants

$ type -t grep

Print only the type word: alias, function, builtin, file, or keyword. Useful in scripts that need to branch on whether a command exists and what kind it is

$ command -v grep

POSIX-portable alternative. Prints the path or alias definition, but with less detail than type. Use this in scripts that must run on /bin/sh

$ type -a ls grep awk sed

Check multiple commands at once. Each one gets its own block of output, so you can audit your whole toolchain in one line

lineage

type has been part of the Bourne shell family since the original sh shipped with Version 7 Unix in 1979, though its behavior has varied across implementations. The POSIX standard specifies type as a required built-in, but leaves the output format unspecified, which is why bash, zsh, ksh, and dash all print slightly different things. Bash added the -a flag to show all resolutions, and -t to emit a machine-readable word (alias, function, builtin, file, keyword). Zsh went further, merging type into its whence built-in and adding flags for path resolution and function source display. The persistent confusion between type, which, and command -v stems from this fragmented history: which is an external command that only searches PATH, command -v is POSIX-portable but terse, and type is the only one that shows the full picture including aliases and functions.