I can't find any official documentation that refers to it as one or the other. What, exactly, is the technical distinction between a command and an operator, anyway?
usually has an alphanumeric string for its name.
is either an external util, a builtin, or a function. Most anything the
typebuiltin produces output for is a command in that sense.
has prefix notation.
usually changes some kind of I/O.
usually is a symbolic string, and may have no name, but might have a nickname.
is not understood by the
typebuiltin, (unless perhaps there's some confusingly named function or script).
more often has infix or suffix syntax.
sometimes directs I/O like a traffic cop, but doesn't change what's in it.
sometimes directs the order of processes.
$() is a command substitution:
- first of all, (or last of all, depending how we look at it), it's a string.
- the string is made up of the text output of those commands listed within.
[ is a shell builtin command:
- it's the
testcommand with a mandatory
[[ is a
bash shell keyword:
- It's like a more versatile and faster
[builtin, but SFAIK with no corresponding
shell keywords include things like
for, that look like commands but behave more like operators that require various sibling keywords as delimiters and syntax. This code runs the
typebuiltin on the output of the
helpbuiltin, which shows a list of left-side keywords and builtins:
COLUMNS=30 help -m | tail -n +9 | tee >(cut -d ' ' -f2) >(cut -c 17-30 | cut -d ' ' -f1) > /dev/null | sort | sed -n "s/.*/type '&'/e"';/found/!p'
Comparing it to a spoken language:
- commands (and some keywords) are like verbs.
- files and strings are nouns.
- operators are like punctuation and prepositions.
In the abstract, operators are just commands with different syntax that could be replaced with workalike prefix style commands along with the rest of them. It probably wouldn't be as convenient to use.
Analytically, the compiled code of a shell could be run through a disassembler, and the operators are again just commands, or rather a series of assembly language commands.
The text in POSIX lists it under 2.6 Word Expansions, along with Tilde Expansion, Parameter Expansion, Arithmetic Expansion, Field Splitting, Pathname Expansion and Quote Removal.
Similarly Bash's manual lists it under Shell Expansions.
The former uses "operator" for redirection operators, and
( etc. so it's not one of them. It's also obviously not a command, so as much or little as the terminology matters, I'd have to say it's neither of those.
From the user perpective, a command substitution is a kind of shell primitive. It is a feature implemented in the shell that performs several actions (launches a subshell, execute a command...) and returns a value (the output of the command). Before the shell performs expansions, a command substitution is usually the argument of a command. In other words, the user gets the result of a shell process using a shell feature.