- Shell handling --- The shell edits the command (splitting it to different rows etc)
Yeah, sort of. The shell gets a command as a single string (usually one line of input), and turns it into a set of strings that actually go to the executable it eventually runs. The shell splits the whitespace separated words from a single string to multiple strings, but also handles quotes, and expands variables etc.
So, something like
ls "$options" "/filename with spaces"
might result to the three strings ls
, -l
(from the value of $options
), and /filename with spaces
(quote removal). These get passed to the exec()
system call that runs the program.
and all of this is done in a different shell than the current one.
No, not really. Some shell expansions (like $( ... )
) spawn subshells to do the hard work, but that doesn't happen for a regular "simple" command line.
- Execution of the outcome after shell handling (in the original shell we work with).
Actually executing the program as the after the command line is parsed is a logically separate step. But technically that happens in another process, since the way for running another program on Unix involves first calling fork()
, which creates a new process as a copy of the first one, and then calling exec()
to replace this copy (of the shell) with the actual program to run (say ls
in the example).
If the command is started with exec
(as in exec ls
, then the forking is skipped, and the shell replaces itself with command it's starting.
Like mentioned in the comments, shell builtins (like echo
in many shells) also often run in the same process, without forking.
(All of the above is somewhat simplified. Real shells may have other features that are not described here.)