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 Commands
where 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 GRAMMAR
inman bash
. – ynn Aug 13 '18 at 16:12