以當前學習進度判斷命令執行優先級!

當運維人員運用LINUX的命令操縱計算機時,只是限於單純的使用命令,而沒有更深入的瞭解命令所執行的優先級,其實在操作系統內部,是有着嚴格的命令執行優先級的,這樣纔夠保證系統的正常運作,避免命令執行時不分主序產生混亂。
在研究命令的主次執行順序之前,我們應該先了解一下liunx系統中命令的分類基礎知識:
(1)內部命令(builtin:內部命令又叫做內建命令,是系統創建之初就寫入到內存之中的,其具有調用速率快的特點,可以通過enable來查看具體的內部命令。
(2)外部命令:外部命令是操作系統中程序所攜帶的指令,由於程序自身較複雜且數據量大,所以外部命令不得全部存儲於內存中,只有在調用時才臨時存儲於內存中。
(3)別名(alias):別名是對當前命令的拓展,可以運用當前已有命令(包括內、外部命令)加以編制,實現更強大或更便捷的組合命令。
命令類型的分辨
如何纔能有效的分辨命令的所屬類型呢,這裏了就要用到type命令了,type的作用就是判斷命令的類別和當前執行路徑信息,下面結合實驗結果加以說明:

[root@localhost ~]# type nano
nano is /bin/nano
[root@localhost ~]# type cat
cat is hashed (/bin/cat)
[root@localhost ~]# type -t cat
file
[root@localhost ~]# type cd
cd is a shell builtin
[root@localhost ~]# type ls
ls is aliased to `ls --color=auto'

這裏可以看到的是,分別對ls,cd,cat,nano幾條命令用type進行查看,通過分析,可以看出:
(1)nano是外部命令,命令路徑爲/bin/nano
(2)cat是存在於hash表中的外部命令
(4)cd是shell的內建命令
(3)ls的當前狀態是別名


現在判斷外部命令是如何判斷執行的,這裏就要提到$PATH變量了,外部命令通過該變量內的路徑,一一對應外部命令進行查詢,能查詢到結果,進行執行,否則報錯

[root@localhost ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin    <==觀察到$PATH變量中是多個路徑的列舉
[root@localhost ~]# type nano
nano is /bin/nano
[root@localhost bin]# ls /bin/nano
/bin/nano    <==根據type只是成功找到nano命令文件
[root@localhost bin]# mv /bin/nano /usr/sbin/   <==延路徑列向右移動nano命令文件
[root@localhost bin]# type nano
nano is /sbin/nano <==觀察到執行路徑隨之改變
[root@localhost bin]# cp /sbin/nano /usr/local/sbin   <==把文件複製一份到列表前列一份
[root@localhost bin]# type nano
nano is /usr/local/sbin/nano    <==觀察到外部命令執行靠左列位置,而忽略了右邊命令文件

結論一:外部命令是延$PATH的內設路徑由左至右搜尋的


由上可以觀察到

cat is hashed (/bin/cat)

那麼hashed是怎麼一回事呢,hash指的就是哈希表,它通過把關鍵碼值映射到表中一個位置來訪問記錄,以加快查找的速度。那麼也就是說系統爲了提高外部命令的查找執行速度,在外部命令執行後,就會將這個路徑臨時記錄到內存中供下次快速查詢使用。下面我們將判斷hash和外部命令的執行優先級

[root@localhost bin]# type cat
cat is hashed (/bin/cat)    <==由於之前使用過cat命令,hash表中以存在路徑
[root@localhost bin]# cat /tmp/anaconda.log    <==可正常使用     
11:32:33,978 DEBUG anaconda: setting locale to: en_US.UTF-8
11:32:48,700 DEBUG anaconda: Entered hub: InitialSetupMainHub
...部分省略...
11:33:19,398 DEBUG anaconda: network spoke (apply), no changes detected
11:33:19,398 DEBUG anaconda: Left spoke: NetworkSpoke
[root@localhost ~]# mv /bin/cat /usr/local/sbin    <==移動hash表中存儲路徑的cat文件到$PATH變量另一路徑,理論上不產生影響
[root@localhost ~]# cat /tmp/anaconda.log    <==但發現執行失敗
-bash: /usr/bin/cat: No such file or directory

由上可知,當hash表中存在了外部命令的緩存路徑,就不會再去搜尋$PATH變量中路徑。

結論二: hash表中外部命令優先級大於$PATH中存儲的外部命令路徑


[root@localhost ~]# type pwd
pwd is a shell builtin

由上可以觀察到cd命令是內部命令,那麼我們僅用它,看看會發生什麼

[root@localhost tmp]# enable -n pwd    <==禁用pwd
[root@localhost tmp]# enable -n    <==查看禁用結果
enable -n pwd    <==確定禁用生效
[root@localhost tmp]# pwd    <==嘗試運行
/tmp    <==依然運行成功

這就奇怪了,爲什麼明明已經被禁用,然後卻仍難能運行呢,爲了研究透徹,我們接着查詢該命令

[root@localhost tmp]# type pwd
pwd is hashed (/usr/bin/pwd)

發現其被存入了hash緩存表,所以仍能運行,但是等等,不是隻有外部命令才能存入這高效又神奇的緩存表麼,你個內部命令,不來就在內存中,還搶什麼搶,其實不盡然

[root@localhost tmp]# type -a pwd
pwd is /usr/bin/pwd

現在再查,暈,原本的內部命令,變成了外部命令運行,也就是說當內部命令沒被禁時,它以內部身份運行,被禁用了,就以hash緩存中外部命令身份運行了。

結論三:內部命令優先級高於hash緩存中外部命令


[root@localhost ~]# type ls
ls is aliased to `ls --color=auto'

這也就是別名,別名好理解了,上篇博客已經說明了別名的設置和使用,這裏也就不在贅述。
下面證實別名的優先級

[root@localhost tmp]# type cd    <==查詢cd類型
cd is a shell builtin    <==證實cd爲內部命令
[root@localhost tmp]# alias cd="echo i am alias"    <==設置與cd同名的別名
[root@localhost tmp]# cd ~    <==嘗試運行cd
i am alias /root    <==執行結果

由執行就過不難看出,生效的爲別名,而非內部命令cd本身的作用,所以得出結論

結論四:別名優先級高於內部命令


總結:通過以上簡單實驗,驗證出了LINUX中命令的執行優先級:別名alias >內部命令>緩存到hash裏的外部命令>外部命令$PATH路徑,並且PATH中靠左側路徑優先於右側搜尋執行

PS:本結論只侷限於當前的學習進度與認知水平,查閱網上資源得知還存在複合命令、函數,也應參與排序,隨着後期的學習,會對本篇博客進行更新,願諒解.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章