- 論壇徽章:
- 0
|
bash命令處理的12個步驟:
1、將命令行分成由固定元字符集分隔的記號;
SPACE, TAB, NEWLINE, ; , (, ), <, >, |, &
記號類型包括單詞,關(guān)鍵字,I/O重定向符和分號。
2、檢測每個命令的第一個記號,查看是否為不帶引號或反斜線的關(guān)鍵字。
如果是一個開放的關(guān)鍵字,如if和其他控制結(jié)構(gòu)起始字符串,function,{或(,則命令實際上為一復(fù)合命令。shell在內(nèi)部對復(fù)合命令進(jìn)行處理,讀取下一個命令,并重復(fù)這一過程。如果關(guān)鍵字不是復(fù)合命令起始字符串(如then等一個控制結(jié)構(gòu)中間出現(xiàn)的關(guān)鍵字),則給出語法錯誤信號。
3、依據(jù)別名列表檢查每個命令的第一個關(guān)鍵字;
如果找到相應(yīng)匹配,則替換其別名定義,并退回第一步;否則進(jìn)入第4步。該策略允許遞歸別名,還允許定義關(guān)鍵字別名。如alias procedure=function
4、執(zhí)行大括號擴展,例如a{b,c}變成ab ac
5、如果~位于單詞開頭,用$HOME替換~。
使用usr的主目錄替換~user。
6、對任何以符號$開頭的表達(dá)式執(zhí)行參數(shù)(變量)替換;
7、對形式$(string)的表達(dá)式進(jìn)行命令替換;
這里是嵌套的命令行處理。
8、計算形式為$((string))的算術(shù)表達(dá)式;
9、把行的參數(shù),命令和算術(shù)替換部分再次分成單詞,這次它使用$IFS中的字符做分割符而不是步驟1的元字符集;
10、對出現(xiàn)*, ?, [ / ]對執(zhí)行路徑名擴展,也稱為通配符擴展;
11、按命令優(yōu)先級表(跳過別名),進(jìn)行命令查尋;
12、設(shè)置完I/O重定向和其他操作后執(zhí)行該命令
一個命令分步處理的結(jié)果:
Further assume that a file exists called .hist537 in user alice's home directory, which is /home/alice, and that there is a double-dollar-sign variable $$ whose value is 2537 (we'll see what this special variable is in the next chapter).
Now let's see how the shell processes the following command:
ll $(type -path cc) ~alice/.*$(($$%1000))
Here is what happens to this line:
1. ll $(type -path cc) ~alice/.*$(($$%1000)) splits the input into words.
2. ll is not a keyword, so Step 2 does nothing.
3. ls -l $(type -path cc) ~alice/.*$(($$%1000)) substitutes ls -l for its alias "ll". The shell then repeats Steps 1 through 3; Step 2 splits the ls -l into two words.
4. ls -l $(type -path cc) ~alice/.*$(($$%1000)) does nothing.
5. ls -l $(type -path cc) /home/alice/.*$(($$%1000)) expands ~alice into /home/alice.
6. ls -l $(type -path cc) /home/alice/.*$((2537%1000)) substitutes 2537 for $$.
7. ls -l /usr/bin/cc /home/alice/.*$((2537%1000)) does command substitution on "type -path cc".
8. ls -l /usr/bin/cc /home/alice/.*537 evaluates the arithmetic expression 2537%1000.
9. ls -l /usr/bin/cc /home/alice/.*537 does nothing.
10. ls -l /usr/bin/cc /home/alice/.hist537 substitutes the filename for the wildcard expression .*537.
11. The command ls is found in /usr/bin.
12./usr/bin/ls is run with the option -l and the two arguments.
Although this list of steps is fairly straightforward, it is not the whole story. There are still five ways to modify the process: quoting; using command, builtin, or enable; and using the advanced command eval.
結(jié)合上面的例子,對bash命令處理的12個步驟有了進(jìn)一步的理解,但是還存在一些疑惑,求大師們解答啊~
1.針對步驟一中的固定元字符集中包含 (, ), 例子中的$(type -path cc)并沒有被分割成兩個記號(token),從步驟7處理時把$(type -path cc)當(dāng)成一個記號(token)可以看出
2.記號類型中:單詞我理解的是包含命令,如echo;普通字符串,如a=123,關(guān)鍵字我理解的就是if,for,while等需要結(jié)合其他的字符進(jìn)行操作的具有特定含義的字符串;但是不太理解做為固定元字符的I/O重定向符和分號是怎么又做為token的呢?? |
|