shell解析命令列的過程以及eval命令,shelleval

來源:互聯網
上載者:User

shell解析命令列的過程以及eval命令,shelleval

本文說明的是一條linux命令在執行時大致要經過哪些過程?以及這些過程的大致順序。

1.1 shell解析命令列

shell讀取和執行命令時的大致操作過程如:

以執行以下命令為例:

echo -e "some files:" ~/i* "\nThe date:$(date +%F)\n$name's age is $((a+4))" >/tmp/a.log

假設在執行該命令前,已賦值變數"name=longshuai"和"a=24",於是重新導向到/tmp/a.log中的結果為:

some files: /root/inotify.sh /root/inotify.sh.oriThe date:2017-08-14longshuai's age is 28

(1).讀取輸入的命令列。

(2).解析引用並分割命令列為各個單詞,各單詞稱為token。其中重新導向所在的token會被儲存下來,直到擴充步驟(5)結束後才進行相關處理,如進行擴充、截斷檔案等。

shell中有3種引用方式:反斜線引用、單引號引用和雙引號引用。

◇ 反斜線轉義:使得元字元變為普通的字面字元。但這隻能對反斜線後一個字元進行轉義。

◇ 單引號引用:單引號內的所有字元全部變為字面符號符號。但注意:單引號內不能再使用單引號,即使使用了反斜線轉義也不允許。

◇ 雙引號引用:使雙引號內所有字元變為字面符號,但"\"、"$"、"`"(反引號)除外,如果開啟了"!"引用曆史命令時,則驚嘆號也除外。

解析引用後,於是就可以將命令列進行單詞分割,分割後的每一部分都稱為一個token。分隔時,不僅分割單個命令,還分割命令列表,所以分隔字元包括:空格、tab、分號、管道符號、&、&&、||、重新導向符號、圓括弧等。

於是上述命令分割為以下幾個token:

如果分割時發現了管道符號,或者是命令列表等組合了多個命令的情況,則每個命令都的token都相互獨立。

(3).檢查命令列結構。主要檢查是否有命令列表、是否有shell編程結構的命令,如if判斷命令、迴圈結構的for/while/select/until,這些命令屬於保留關鍵字,需要特殊處理。

(4).對第一個token進行別名擴充。如果檢查出它是別名,則擴充後回到(2)再次進行token分解過程。

(5).進行各種擴充。擴充順序為:大括弧擴充;波浪號擴充;參數、變數和命令替換、算術擴充(如果系統支援,此步還進行進程替換);單詞拆分;檔案名稱擴充。

不同引號的引用方式,將改變擴充的起始步驟,正如所畫,沒有任何引號時將從頭到尾全部擴充,使用單引號時將完全不會進行任何擴充,使用雙引號時將從變數替換開始繼續擴充。

①大括弧擴充:如/tmp/{a,b}.log擴充為/tmp/a.log和/tmp/b.log。

②波浪號擴充:擴充為家目錄。如root使用者下的~/.ssh擴充為/root/.ssh。

③變數擴充:即操作和替換變數值。如$a替換為它的值24,${name:-longshuai}替換為longshuai。

④命令替換:此過程將執行命令替換中的命令,並將結果替換到token的對應位置處。

⑤進程替換:將進程的執行結果替換到對應位置。類似於命令替換。替換格式為"<(cmd_list)"和">(cmd_list)",例如"cat <(cat /etc/hosts)"。redhat系列應該都支援進程替換。

⑥算術擴充:計算算術值,並將計算結果替換到對應位置處。例如$((a+4))替換為28。

經過以上幾種擴充後,得到如下結果:

⑦單詞拆分:掃描變數擴充、命令替換和算術擴充的結果,對非引號內的結果按照$IFS的值對這些結果進行單詞分割。

注意,如果沒有進行擴充,或者擴充結果使用引號包圍了,則不會進行此步的單詞拆分。

預設情況下,$IFS值為"   \t\n",所以擴充結果中每遇到空格、定位字元、分行符號都將被分割為兩個單詞。

這一步其實很容易犯錯,典型的是test命令。例如變數name="Ma longshuai",則test $name == "longshuai"將報錯,因為變數擴充後該語句變為test Ma longshuai == "longshuai",由於是變數替換,所以隨後進行單詞拆分,使得Ma和longshuai被拆分為兩個單詞,但實際上它們共同組成變數name的值。

所以,為了正確操作變數替換和命令替換,盡量將它們使用引號包圍。例如test "$name" == "longshuai",這時將不會進行單詞拆分。

⑧檔案名稱擴充:對每個token進行搜尋,將搜尋"*"、"?"和"["符號,搜尋到了將進行檔案名稱擴充。例如將上面的"/root/i*"擴充為"/root/inotify.sh /root/inotify.sh.ori"。

(6).引號去除。經過上面的過程,該擴充的都擴充了,不需要的引號在此步就可以去掉了。

所以得到如下結果。

(7).搜尋和執行命令。

單詞分割後,複雜的命令列將由各個簡單命令結構組成。於是可以搜尋每個簡單命令結構的第一個token中的命令,同時還帶有一系列命令選項。例如上面的"echo"和"-e"。

如果命令中不含任何斜杠:

①則先判斷是否有此名稱的shell function存在,如果有則調用它,否則進行下一步搜尋。

②判斷該命令是否為bash內建命令,如果是則執行它,否則進行下一步搜尋。

③從$PATH的路徑下搜尋該命令,如果搜尋到了,則執行,否則報錯。

如果命令中包含一個或多個斜杠,則進行相對路徑擴充、絕對路徑尋找,找到了則執行,否則報錯。

(8).返回退出狀態代碼。

1.2 eval命令

正常情況下,當搜尋到命令時將會執行命令,但如果搜尋到的命令為eval時,則處理方式有所不同。

它的文法格式為:

eval command arguments

按照前文所述shell解析過程,將最終得到eval command和一系列擴充後的選項、參數,當搜尋命令時,搜尋到的結果為eval命令,於是eval命令將除了eval命令(以及eval的選項)的所有token再次傳遞給shell進行二次解析。但重新導向所在token除外,因為重新導向token早已被shell儲存下來,所以不會再次截斷檔案。

也就是說,"command arguments"被當作eval命令的參數,被傳遞給shell進行解析、執行。

執行過程如所示:

使用樣本來說明:

[root@xuexi ~]# a=24;name='long$a'     # 注意,使用的是單引號,禁止$a被擴充

如果直接執行echo $name,則結果為"long$a",但如果執行eval echo $name,結果將是"long24"。

[root@xuexi ~]# eval echo $namelong24

首先shell按照正常過程解析,在變數替換時由於使用了單引號,所以$name第一次變數替換的結果為"long$a",直到命令搜尋時發現搜尋到的命令是eval命令,執行eval命令,該命令將其參數"echo long$a"再次傳遞給shell,相當於在標準輸入中輸入了"echo long$a",於是shell進行二次解析,這次的變數替換將$a替換為24,最後搜尋命令發現是echo命令,於是最終得到"long24"。

關於eval,更多的用法是間接變數$$var的用法,在bash shell中需要在第一個$前加上反引號,即\$$var,這麼做的原因是顯然的:防止第一次shell解析時被當作特殊變數"$$"被擴充。

[root@xuexi ~]# a=b[root@xuexi ~]# b=haha[root@xuexi ~]# eval echo \$$ahaha

 

註:本文並非一定準確,只是根據man bash總結而來。如有錯誤,請明確指出。多謝

 

回到系列文章大綱:http://www.cnblogs.com/f-ck-need-u/p/7048359.html

轉載請註明出處:http://www.cnblogs.com/f-ck-need-u/p/7426371.html註:若您覺得這篇文章還不錯請點擊下右下角的推薦,有了您的支援才能激發作者更大的寫作熱情,非常感謝!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.