This article explains what the process of a Linux command is going through when it executes. And the approximate sequence of these processes.
1.1 Shell parsing command line
The approximate operation of the shell when reading and executing commands is as follows:
Take the following command as an example:
Echo " Some files: " " \nthe date:$ (date +%f) \n$name ' s is $ ((a+4) ) " >/tmp/a.log
Assuming that the variable "Name=longshuai" and "a=24" are assigned before the command is executed, the result is redirected to/tmp/a.log:
some files: /root/inotify.sh /root/inotify.sh.ori
The date:2017-08-14
longshuai‘s age is 28
(1). Read the input command line.
(2). Parse the reference and split the command behavior of each word, each word is called token. The token where the redirect is located is saved until the extension step (5) finishes, such as extending, truncating the file, and so on.
There are 3 types of references in the shell: backslash reference, single quote, and double quotation mark reference.
◇ Backslash escape: Makes the meta-character into a normal literal character. However, this can only be escaped with a backslash followed by one character.
◇ Single Quote quote: All characters in single quotation marks become literal symbols. Note: Single quotation marks cannot be used in single quotes, even if a backslash escape is used.
◇ Double Quote quote: Make all characters in double quotation marks literal, except "\", "$", "'" (anti-quotation marks), if "!" is turned on. When you reference a history command, the exclamation mark is also excluded.
After parsing the reference, the command line can be divided into words, and each part of the split is called a token. When separated, not only splits a single command, but also splits the list of commands, so the delimiter includes: spaces, tabs, semicolons, pipe symbols, &, &&, | |, redirection symbols, parentheses, and so on.
The above command is then divided into the following tokens:
If a pipe symbol is found in the split, or when multiple commands are combined, such as a list of commands, the tokens of each command are independent of each other.
(3). Check the command line structure. Main check whether there is a command list, whether there are shell programming structure commands, such as if judgment command, looping structure of the for/while/select/until, these commands belong to the reserved keyword, need special handling.
(4). alias extension for the first token. If it is checked out as an alias, then the extension returns to (2) the token decomposition process again.
(5). Perform various extensions. The expansion order is: curly brace extension, tilde extension, parameter, variable and command substitution, arithmetic extension (process substitution if supported by the system), Word splitting, filename extension.
The way in which different quotes are quoted will change the starting step of the extension, which, as it is drawn, expands from start to finish without any quotation marks, without any extension at all, using double quotation marks to continue extending from the variable substitution.
① curly braces extension: such as/tmp/{a,b}.log extension to/tmp/a.log and/tmp/b.log.
② tilde Extension: extended to home directory. such as the root user under the ~/.ssh extension to/root/.ssh.
③ variable extension: The value of the action and substitution variables. Replace $ A with its value 24,${name:-longshuai} with Longshuai.
④ command substitution: This procedure executes the command in command substitution and replaces the result with the corresponding location of the token.
⑤ process substitution: Replaces the execution result of the process with the corresponding location. Similar to command substitution. Replace the format with "< (cmd_list)" and "> (cmd_list)", such as "Cat < (cat/etc/hosts)". The Redhat series should all support process substitution.
⑥ arithmetic extension: Calculates the arithmetic value and replaces the calculated result with the corresponding position. For example, $ ((a+4)) is replaced with 28.
After the above several expansions, the following results are obtained:
⑦ Word splitting: The result of scanning variable expansion, command substitution, and arithmetic extension, and the word segmentation of the results in non-quotation marks according to the values of $ifs.
Note that if the extension is not extended, or if the extended result is surrounded by quotation marks, then the word split will not be made for this step.
By default, the $IFS value is "\t\n", so each space, tab, newline character that is encountered in the extended result is divided into two words.
This step is in fact easy to make mistakes, typically the test command. For example, the variable name= "Ma Longshuai", then test $name = = "Longshuai" will be an error, because the variable expands after the statement becomes test Ma Longshuai = = "Longshuai", because it is a variable substitution, so then the word split, Causes the MA and Longshuai to be split into two words, but in fact they collectively make up the value of the variable name.
Therefore, in order to correctly manipulate variable substitution and command substitution, try to enclose them in quotation marks. For example, test "$name" = = "Longshuai", then word splitting will not be done.
⑧ filename extension: Searches for each token, searches for "*", "?" and the "[" Symbol, the search for the filename extension will be made. For example, extend the above "/root/i*" to "/root/inotify.sh/root/inotify.sh.ori".
(6). Quotation marks are removed. After the above procedure, the extension is expanded, and the unwanted quotes can be removed in this step.
So we get the following result.
(7). Search and execute commands.
After the word is split, the complex command line is composed of simple command structures. You can then search for the commands in the first token of each simple command structure with a series of command options. For example, "echo" and "-e" above.
If the command does not contain any slashes:
① first determines if there is a shell function with this name, and if there is one, call it or proceed to the next search.
② determines whether the command is a bash built-in command, and if so, performs the next search.
③ Search the command from the $path path, if the search is done, then execute, otherwise error.
If the command contains one or more slashes, then the relative path extension, absolute path lookup, found is executed, otherwise error.
(8). Returns the exit status code.
1.2 eval command
Normally, commands are executed when the command is searched, but are handled differently if the command you are searching for is eval.
Its syntax format is:
eval command Arguments
Following the shell parsing process described earlier, the Eval command and a series of extended options and parameters are eventually obtained, and when the search command is searched, the result of the search is the eval command, so the eval commands will be in addition to the Eval command (and the eval option) All tokens are passed to the shell again for two parsing. However, the redirect token is not the same as the token, since the redirect tokens are already saved by the shell, so the file will not be truncated again.
That is, "command arguments" is treated as a parameter to the Eval command and is passed to the shell for parsing and execution.
The execution process is as follows:
Use examples to illustrate:
[[email protected] ~] # a = 24; name = ‘long $ a’ # Note that single quotes are used to prevent $ a from being expanded
If the echo $name is executed directly, the result is "long$a", but if the eval echo $name is executed, the result will be "long24".
[[email protected] ~]# eval echo $name
long24
First the shell according to the normal process parsing, in the variable substitution due to the use of single quotation marks, so $name the first variable substitution result is "long$a", until the command search found that the command is the eval command, execute the eval command, the command will its parameters "echo long$a" Passed to the shell again, equivalent to entering the "Echo long$a" in the standard input, so the shell is parsed two times, this time the variable substitution will replace $ A 24, the last search command found the echo command, and finally get "long24".
With respect to eval, more usage is the use of indirect variable $ $var, in bash shell need to precede the first $ with an anti-quote, i.e. \$ $var, the reason for this is obvious: prevent the first shell parsing as a special variable "$$" is extended.
[[email protected] ~]# a=b
[[email protected] ~]# b=haha
[[email protected] ~]# eval echo \$$a
haha
Note: This article is not necessarily accurate, but based on the man bash summary. If there are any errors, please state clearly. Thanks a lot
Back to series article outline:http://www.cnblogs.com/f-ck-need-u/p/7048359.html
Reprint Please specify source:http://www.cnblogs.com/f-ck-need-u/p/7426371.html Note: If you think this article is not bad please click on the lower right corner of the recommendation, with your support to inspire the author more enthusiasm for writing, thank you very much!
Shell parsing command-line procedures and Eval commands