如何知道什麼是命令、系統呼叫、bash 內置函式等?
一位同事最近問“什麼是
man
”?在得知並非所有可從 Bash CLI 訪問的東西都是命令後,我很謹慎地呼叫man
命令。
man man
只是稱它為介面:NAME man - an interface to the on-line reference manuals
man
有一個執行檔:$ which man /usr/bin/man $ file /usr/bin/man /usr/bin/man: ELF 64-bit LSB shared object
程序也是如此
man
,因為它有一個執行檔?其他名詞可以man
是什麼?用什麼名詞來形容呢?真的,我對如何確定任意是什麼的一般情況感興趣,這只是一個thing on the cli
例子man
。就此而言,可以在 Bash CLI 上使用的所有東西是什麼詞?一個包含命令、別名、系統呼叫等的詞?
在 POSIX 術語中,任何可以要求 shell 做某事的東西都是命令:
用於執行特定任務的 shell 指令。
所以
man man
是一個命令,原樣(技術上)
man
man
也是一個實用程序:一個程序,不包括作為 Shell 命令語言的一部分提供的特殊內置實用程序,可以通過名稱從 Shell 呼叫以執行特定任務或相關任務集。
(這裡的排除並不重要;之所以提到它,是因為特殊的內置實用程序具有特定的屬性。)
要找出給定命令是什麼,請使用
type
. 這將告訴您它是內置的,還是PATH
(以及在哪裡)上的程序,或別名等(或未知)。請注意,系統呼叫不能用作 shell 命令。
另請參閱它們是命令還是實用程序?內置命令和非內置命令有什麼區別?
從最低層開始:
系統呼叫
系統呼叫是使用者態任務(必須)用來從核心請求某些服務並執行到特權核心模式的方式。
例如,假設 C 是您的程式語言,並且您希望您的任務更改其目前目錄,您需要在程序中插入一條chdir()指令。
當然,這些過程不能立即從命令行訪問。vg 在命令行輸入 chdir 不會呼叫 chdir 系統呼叫。
所有可用系統呼叫的列表當然取決於核心,唯一可靠的來源當然是
include/linux/syscalls.h
核心原始碼分發的標頭檔。指示
CLI 是您正在執行的任務的介面。您輸入的任何內容都稱為指令,因為它應該指示任務完成某些操作。
命令
您鍵入的內容將首先通過解釋器,該解釋器將對您鍵入的標記執行一些詞法分析,並且在 shell 的特定情況下,可能會辨識命令的名稱(理解為不是變數賦值)並順便決定它需要求助於另一個程序才能滿足您的要求。然後它將派生一個子程序,該子程序將執行該其他程序的二進製文件。
但是在某些特殊情況下,任務可能更容易滿足請求,而無需借助外部程序(例如微積分),或者更重要的是,必須在內部執行您的請求。
內置命令
回到我們最初更改活動目錄的意願,使用者將發出眾所周知的 shell 命令
cd
。使用者真正想要的是改變他的 shell 的目前目錄。而且因為 chdir 系統呼叫只改變呼叫者的目前工作目錄,shell 不能派生另一個不會改變其父程序的程序。shell 必須在內部執行 chdir 系統呼叫。
yourshellname
所有手冊頁中都列出了 shell 內置命令。別名
別名只不過是任何使用者都可以設置的同義詞,並將由命令行解釋器翻譯成所需的字元串(應該代表對 shell 的任何合法指令。)
alias
借助 shell 內置命令,可以獲得所有目前活動別名的列表。