シェル組み込みコマンドの詳細

シェル組み込みコマンドの詳細

からバッシュマニュアル、言う

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

ご覧のとおり、[これは他のシェルの組み込み機能と同様に、組み込みコマンドと外部コマンドです。しかし、これがシェル自体にコンパイルされ、シェル組み込みであるという事実は変わりません。

関連情報