As steeldriver said, SHELL=/bin/sh lesspipe is a simple command, which is defined as a sequence of:
- optional variable assignments (here
SHELL=/bin/sh), followed by...
- blank-separated words and redirections (here
lesspipe), terminated by...
- a control operator, which includes a newline character.
Your first example:
ls echo
is actually a valid command: only the first word is treated as a command to execute, the rest are given to that command as parameters¹.
In the case of a ls command, if there is a sub-directory named echo in the current directory, its contents will be listed; if there is a non-directory named echo, its name will be displayed². If neither is true, the command will return an error and display a No such file or directory error message.
Your second example:
abc=hello echo $abc
is again a simple command with a variable assignment, but it also includes a variable expansion ($abc). The EXPANSION chapter of man bash defines the various kinds of expansion and their order of operations.
After the command line has been split into words, the shell checks for expansions:
- brace expansion: nothing applicable
- tilde expansion: nothing applicable
- parameter and variable expansion: here
$abc is replaced by the current value of shell or environment variable named abc. But since this command line has not been executed yet, the variable assignment earlier on the line (abc=hello) is not in effect yet. As a result, $abc is replaced by whatever value abc had before, or an empty string if it was not set. The empty string is then removed completely since it was not quoted.
- command substitution: nothing applicable
- arithmetic expansion: nothing applicable
- word splitting: the only candidate for this would have been the result of the
$abc variable expansion, but there is nothing to split in a null string.
- pathname expansion: nothing applicable
Once the expansions are done, the variable abc in the environment of the to-be-started utility is set to value "hello" and the command echo is executed. It outputs just a single blank line.
¹ strictly speaking, ls is also passed as argument, as its argv[0]. ls uses that argument to know how it was invoked, uses it as well in the error messages it outputs, but doesn't consider it as an option or file to act upon.
² if it is a symbolic link, but its target can't be resolved, some ls implementations will however output an error message as if the file didn't exist
SHELL GRAMMAR-Simple Commandswhere it says A simple command is a sequence of optional variable assignments followed by blank-separated words and redirections, and terminated by a control operator. but unless you're a syntax weenie that's rather hard to recognize IMHO – steeldriver Aug 13 '18 at 15:34SHELL GRAMMARinman bash. – ynn Aug 13 '18 at 16:12