からバッシュマニュアル、言う
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
シェル組み込みコマンドのリストが表示されます。たとえば、シェルは組み込みとしてマークされ、一覧[
表示されます。kill
しかし、実際の位置は次のとおりです。
/usr/bin/[
/bin/kill
私はこれがbuiltin
コマンドが/bin/bash
実行可能ファイルにコンパイルされることを意味すると思います。だから私を本当に混乱させるのはこれです。訂正します。しかし、builtin
これは実際にはシェルの一部ではありませんが、どうすればaになりますか?
答え1
シェルに組み込まれたコマンドは、一般にパフォーマンスを向上させるため、組み込まれています。呼ぶ外部 printf
たとえば、組み込みのprintf
。
一部のユーティリティはそうではないので必要内蔵されています。特別でない場合は、次のようにcd
なります。外部便利です。これにより、スクリプトが組み込みの同等の機能を提供しないシェルによって解釈されてもスクリプトは中断されません。
一部のシェル組み込みコマンドは、同等の外部コマンドの拡張も提供します。たとえば、Bashはprintf
次のことができます。
$ printf -v message 'Hello %s' "world"
$ echo "$message"
Hello world
(変数として印刷)外部では、/usr/bin/printf
現在のシェルセッションのシェル変数にアクセスできず、変更できないため、これはできません。
組み込みユーティリティも利用可能いいえ拡張コマンドラインは特定の長さより短くなければなりません。行為
printf '%s\n' *
printf
だからシェル内蔵命令なら安全だ。コマンドラインの長さの制限は、execve()
外部コマンドの実行に使用されるCライブラリ関数に由来します。コマンドラインと現在の環境がARG_MAX
バイトより大きい場合(getconf ARG_MAX
シェルを参照)、呼び出しはexecve()
失敗します。このユーティリティがシェルに組み込まれている場合は、execve()
呼び出す必要はありません。
組み込みユーティリティ$PATH
では、組み込みコマンドを無効にするには、bash
次のコマンドを使用します。
enable -n printf
短いユーティリティのリストがあります。必要シェルに組み込まれています(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
理論的にはあるかもしれません(しかしそれほど多くのことはしません)。
答え2
あなたは(非常に当然)いくつかの組み込み関数の存在のために混乱しています。両方組み込み関数としてそして外部コマンドで。したがって、たとえば、コマンドがあることは正しいですが、/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
ご覧のとおり、[
これは他のシェルの組み込み機能と同様に、組み込みコマンドと外部コマンドです。しかし、これがシェル自体にコンパイルされ、シェル組み込みであるという事実は変わりません。