了解 shell 內置命令
在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 -b
時bash 4.4
,我會收到所有 shell 內置命令的列表。例如,我看到[
並被kill
列為 shell 內置函式。但他們的實際位置是:/usr/bin/[ /bin/kill
我認為這
builtin
意味著命令被編譯成/bin/bash
執行檔。那麼真正讓我困惑的是:請糾正我,但是一個單獨的命令怎麼可能是 abuiltin
,當它實際上不是 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_MAX
shell),呼叫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
理論上可以有(但它不會做太多)。