2017-04-01 23 views
2

我對內置shell的定義有點困惑。根據Bash Reference Manual,對於任何內置的,shell都會直接執行該命令,而不會調用另一個程序。究竟是什麼意思,「命令直接執行」?例如,讓我們來看看內置cdshell內置執行

$ which cd 
/usr/bin/cd 
$ type cd 
cd is a shell builtin 

現在,讓我們來看看非內置grep

$ which grep 
/usr/bin/grep 
$ type grep 
grep is /usr/bin/grep 

看來,cd是一個獨立的二進制文件。執行cd(或任何其他內置)與執行grep(或任何其他非內建)有什麼不同?

+2

'cd'在這裏是一個特殊情況,因爲它必須是一個內建的任何有用的效果。 '/ usr/bin/cd'實際上是無用的,因爲它作爲自己獨立的進程運行,它改變它自己的目錄然後退出 - 但是**不會改變調用它的單獨程序的目錄。 –

+2

(...如果我們要迂腐的話,那麼'/ usr/bin/cd'有一點點用處 - 它決定了你是否可以*通過實驗改變到給定的目錄。) –

回答

5

某些命令既作爲內置的shell存在,也作爲單獨的程序存在。 which命令(這是一個單獨的程序,而不是內置的!)只能找到單獨的程序,並且永遠不會打擾builtin。嘗試使用type readarraywhich readarray來查看僅作爲內置函數存在的命令。

重要的是要注意內置版本和外部程序可能會有所不同。在某些情況下,您可能更喜歡依賴內建(即如果您知道腳本將用於何種外殼,但不確定要執行哪個外部版本),或者相反。

您可以使用其完整路徑調用外部程序(這將繞過內建)。

當調用一個外部程序時,操作系統將啓動一個單獨的進程,而內建程序是shell程序本身的一部分,因此會有更低的開銷。在很多情況下,這種開銷並不重要,但是如果您要多次執行命令,可能會對腳本的性能產生重大影響。

+0

感謝回覆!!那很有意思。如果這些二進制文件已經作爲內置函數存在,那麼這些二進制文件在哪裏呢?他們曾經使用過嗎? –

+0

@AlexanderKohler,你只能從shell *中使用shell內建*。任何使用'execv'-family系統調用直接執行其他程序的東西都不能使用shell內置函數,而需要外部二進制文件。 –

+1

@AlexanderKohler,...所以,'找到。 -exec foo {} +'總是將'foo'作爲一個外部可執行文件調用,而不管這個名字是否存在內置函數(shell函數,別名等)。 –

2

除了弗雷德的正確答案:

我明白您對內建和外部命令的衝突。 cd命令實際上是一個小示範。

例如我的系統上,情況如下:

$ which cd # gives no output 
$ whereis cd # again, no path found 
cd: 
$ type -a cd # verifies that it's a real builtin command 
cd is a shell builtin 

這清楚地表明,在外部程序換算的cd命令沒有我的機器上安裝。在你的情況下,which cd顯示在/usr/bin/cd下安裝了額外的cd命令(單獨的程序)。

有時不清楚何時輸入cd是否打算調用內置命令或外部命令。爲了確保,你真的調用內置cd命令,就可以執行以下命令:

$ builtin cd 

從內置cd命令的幫助頁面:

$ help builtin 

內置:內置[殼 - 內建[arg ...]] 執行shell內置函數。現在

Execute SHELL-BUILTIN with arguments ARGs without performing command 
lookup. This is useful when you wish to reimplement a shell builtin 
as a shell function, but need to execute the builtin within the function. 

可以看到builtin命令如何使用強制執行shell內建命令的執行。這在特殊情況下非常有用。

此外,還可以(它實際上是顯而易見的)期望從內置命令 [source]更好的性能:

在一般情況下,在腳本叉掉一個子進程的外部命令, [*]而猛砸內置呢不。由於這個原因,內置函數更快地執行 ,並使用比它們的外部 等效命令少的系統資源。

+0

Ooo,我不知道這個'builtin'命令。現在這一切都變得更有意義。謝謝!! :) –

+0

呵呵,當我第一次偶然發現'builtin'命令時,事情對我來說就變得更加清晰了。 –