bash manual には、
Builtin commands are contained >>> within <<< the Shell itself
また、 this 回答では、
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
を実行すると、すべてのシェル組み込みコマンドのリストが表示されます。たとえば、[
とkill
がShellビルトインとしてリストされていることがわかります。しかし、実際の場所は次のとおりです。
/usr/bin/[
/bin/kill
builtin
は、コマンドが/bin/bash
実行可能ファイルにコンパイルされることを意味すると思いました。だから私を本当に混乱させているのは何ですか:私を訂正してください、しかしそれが実際にシェルの一部ではない場合、どのようにして別のコマンドをbuiltin
にすることができますか?
シェルに組み込まれているコマンドは、パフォーマンスが向上するために組み込まれていることがよくあります。たとえば、externalprintf
の呼び出しは、組み込みのprintf
を使用するよりも低速です。
一部のユーティリティはneedを組み込まないため、cd
のような特別なものでない限り、-externalユーティリティとしても提供されます。これは、組み込みの同等機能を提供しないシェルによってスクリプトが解釈されてもスクリプトが壊れないようにするためです。
一部のシェルのビルトインは、外部の同等のコマンドに対する拡張機能も提供します。 Bashのprintf
など。
_$ printf -v message 'Hello %s' "world"
$ echo "$message"
Hello world
_
(変数に出力する)外部_/usr/bin/printf
_は、現在のシェルセッションでシェル変数にアクセスできないため(そしてそれらを変更できないため)、これを行うことはできません。
組み込みユーティリティにはnotもあり、拡張されたコマンドラインは特定の長さよりも短くなければならないという制限があります。している
_printf '%s\n' *
_
したがって、printf
がシェル組み込みコマンドである場合は安全です。コマンドラインの長さの制限は、外部コマンドの実行に使用されるexecve()
Cライブラリ関数に起因します。コマンドラインと現在の環境が_ARG_MAX
_バイトより大きい場合(シェルの_getconf ARG_MAX
_を参照)、execve()
の呼び出しは失敗します。ユーティリティがシェルに組み込まれている場合、execve()
を呼び出す必要はありません。
組み込みユーティリティは、_$PATH
_にあるユーティリティよりも優先されます。 bash
の組み込みコマンドを無効にするには、たとえば、.
_enable -n printf
_
needがシェルに組み込まれるユーティリティの短いリストがあります(POSIX標準の 特別な組み込みのリスト から取得)
_break
colon (:)
continue
dot (.)
eval
exec
exit
export
readonly
return
set
shift
times
trap
unset
_
これらは、現在のシェルセッションの環境とプログラムフローを直接操作するため、組み込みが必要です。外部のユーティリティはそれを行うことができません。
興味深いことに、cd
はこのリストの一部ではありませんが、POSIX 次のように言います については、
cd
は現在のシェル実行環境に影響を与えるため、常に通常のシェル組み込みとして提供されます。次のいずれかなど、サブシェルまたは別のユーティリティ実行環境で呼び出された場合:_(cd /tmp) Nohup cd find . -exec cd {} \;
_呼び出し元の環境の作業ディレクトリには影響しません。
したがって、「特別な」ビルトインは外部の対応物を持つことができないと想定していますが、cd
は理論的にはそうすることができます(ただし、あまり機能しません)。
一部のビルトイン両方がビルトインとして存在するおよびが外部コマンドとして存在するという事実に(非常に理解できるほど)混乱しています。したがって、たとえば/bin/[
コマンドがあるというのは正しいですが、「実際の場所」が/bin
にあるという意味ではありません。
これをテストする簡単な方法は、type
を-a
スイッチで実行して、コマンドのすべての使用可能なインスタンスを表示することです。私のArchシステムでは次のように表示されます:
$ type -a [
[ is a Shell builtin
[ is /sbin/[
[ is /usr/sbin/[
[ is /usr/bin/[
/sbin
、/usr/sbin
、/bin
はすべて/usr/bin
を指すシンボリックリンクであるため、外部[
は1つだけであることに注意してください。
$ readlink -f /usr/sbin /sbin /bin/
/usr/bin
/usr/bin
/usr/bin
ご覧のとおり、[
は組み込みコマンドと外部コマンドの両方であり、同じことが他のさまざまなシェル組み込みコマンドにも当てはまります。ただし、これらはシェル自体にコンパイルされた組み込みシェルでもあるという事実は変わりません。