Bash

了解 shell 內置命令

  • May 10, 2018

bash 手冊中,它寫道

Builtin commands are contained >>> within <<< the shell itself

此外,這個答案指出

A built-in command is simply a command that the shell carries out itself,
instead of interpreting it as a request to load and run some
>>> other program <<<

當我執行compgen -bbash 4.4,我會收到所有 shell 內置命令的列表。例如,我看到[並被kill列為 shell 內置函式。但他們的實際位置是:

/usr/bin/[
/bin/kill

我認為這builtin意味著命令被編譯成/bin/bash執行檔。那麼真正讓我困惑的是:請糾正我,但是一個單獨的命令怎麼可能是 a builtin,當它實際上不是 shell 的一部分時呢?

內置在 shell 中的命令通常是內置的,因為這可以提高性能。例如,呼叫external printf比使用 built-in 慢printf

由於某些實用程序不需要內置,除非它們是特殊的,例如cd,它們也作為外部實用程序提供。這樣一來,如果腳本由不提供內置等效項的 shell 解釋,它們就不會中斷。

一些 shell 的內置函式還提供了對外部等效命令的擴展。Bash 的printf,例如能夠做到

$ printf -v message 'Hello %s' "world"
$ echo "$message"
Hello world

(列印到變數)外部/usr/bin/printf根本無法執行此操作,因為它無法訪問目前 shell 會話中的 shell 變數(並且無法更改它們)。

內置實用程序也沒有限制,即它們的擴展命令行必須短於某個長度。正在做

printf '%s\n' *

因此如果printf是一個 shell 內置命令是安全的。命令行長度的限制來自execve()用於執行外部命令的 C 庫函式。如果命令行和目前環境大於ARG_MAX字節(參見getconf ARG_MAXshell),呼叫execve()將失敗。如果該實用程序內置在 shell 中,execve()則不必呼叫。

內置實用程序優先於$PATH. 要禁用 中的內置命令bash,請使案例如

enable -n printf

有一個需要內置到 shell 中的實用程序的簡短列表(取自 POSIX 標準的特殊內置列表

break
colon (:)
continue
dot (.)
eval
exec
exit
export
readonly
return
set
shift
times
trap
unset

這些需要內置,因為它們直接操縱目前 shell 會話的環境和程序流。外部實用程序將無法做到這一點。

有趣的是,cd它不在此列表中,但 POSIX 對此做了以下說明:

由於cd影響目前的 shell 執行環境,它始終作為 shell 正常內置提供。如果在子 shell 或單獨的實用程序執行環境中呼叫它,例如以下之一:

(cd /tmp)
nohup cd
find . -exec cd {} \;

它不會影響呼叫者環境的工作目錄。

因此,我假設“特殊”內置程序不能有外部對應項,而cd理論上可以有(但它不會做太多)。

引用自:https://unix.stackexchange.com/questions/442945