printf may be a shell builtin and an external executable.
List every resolution Bash can use for the name.
Assume there is no same-name alias or shell function.
Which command is appropriate?
Bash type identifies command kinds and type -a lists every matching resolution, including builtins and PATH entries.
Detailed explanation
which printfIncorrect. which normally searches PATH and may omit shell builtins and alternate resolutions.
Finding an external printf does not also identify the Bash builtin. Separate where a file resides from whether all shell definitions were included.
command -v printfIncorrect. command -v reports one resolution, not all of them.
Under the stated premise, command -v printf reports printf as one resolution. It is useful for the selected result, but does not enumerate the same-name external file.
whereis printfIncorrect. whereis searches files and manuals rather than Bash's full resolution order.
whereis locates related files rather than listing how the current Bash classifies and resolves a name.
type -a printfCorrect. type -a lists all resolutions known to Bash.
type with -a includes the builtin and the same-name executable on PATH. The verification deliberately supplies one external fixture and contrasts the list with command -v.
Try it yourself
An example you can run in a temporary verification environment.
LAB_DIR=$(mktemp -d) || exit 1
printf '#!/bin/sh\nexit 0\n' > "$LAB_DIR/printf"
chmod u+x "$LAB_DIR/printf" || exit 1
(
export LC_ALL=C
PATH="$LAB_DIR"
hash -r
LAB_ALL=$(type -a printf)
builtin printf '%s\n' "${LAB_ALL//"$LAB_DIR"/<LAB_DIR>}"
builtin printf 'first=%s\n' "$(command -v printf)"
)
rm -- "$LAB_DIR/printf"
rmdir -- "$LAB_DIR"Official references
Expected result
printf is a shell builtin
printf is <LAB_DIR>/printf
first=printfKey points
- Bash builtins versus external commands
- type -a
- Why which is incomplete
Notes
- Environment: Bash 5.2 / GNU coreutils in a fresh process without user startup files, with errexit off. Comparison PATH, LC_ALL, hash, alias and function settings stay in a subshell; HOME is unchanged.
- Create one external fixture in a new temporary directory and restrict PATH only inside the subshell. The fixture is inspected rather than executed.
- Only the temporary path in the actual type -a output is replaced by <LAB_DIR>. LC_ALL=C and the cleared command hash are confined to that subshell.
Foundation review
The basic case has two kinds of candidate
This question excludes aliases and same-name functions to focus on a builtin and an external executable. Defining an alias or function can add that definition to the list of candidates.
All candidates versus one selected result
type -a and command -v answer different questions. Both can inspect a name without running the external program.
Filesystem location is a different query
Locating a file with which or whereis does not establish that Bash builtin information was included.