$ which echo
echo: shell built-in command.
$ which ls
/bin/ls
$ which cat
/bin/cat
なぜ、エコーのような独立したユーティリティではありませんls
、ps
、cat
など?なぜシェル固有なのですか?正当な理由はありますか?
echo
最も確実なのは Bash ビルトインです。実際、それはすべての主要な現代のシェルに組み込まれています。
$ which echo
echo: shell built-in command.
$ which ls
/bin/ls
$ which cat
/bin/cat
なぜ、エコーのような独立したユーティリティではありませんls
、ps
、cat
など?なぜシェル固有なのですか?正当な理由はありますか?
echo
最も確実なのは Bash ビルトインです。実際、それはすべての主要な現代のシェルに組み込まれています。
回答:
ビルトインには2つのクラスがあります。
一部のコマンドは、外部の場合は機能できないため、シェルプログラム自体に組み込む必要があります。
cd
外部の場合は、自分のディレクトリしか変更できないため、そのようなものです。シェルの現在の作業ディレクトリには影響しません。(参照:なぜcd
プログラムではないのですか?)
他のクラスのコマンドは、純粋に効率化のためにシェルに組み込まれています。
manページには言及して組み込みコマンドのセクションあり、と、このクラスのコマンドの例としては。dash
printf
echo
test
Unixシステムでは、常に、2番目のクラスのコマンド用に個別の実行可能ファイルが含まれています。これらの個別の実行可能ファイルは、使用する可能性のあるすべてのシェルにも組み込まれていますが、使用したすべてのUnixyシステムで引き続き使用できます。(POSIXでは、実際にこれらの実行可能ファイルが存在する必要があります。)
echo
AT&T Unix System Vリリース3.1のシェルに組み込まれたと思います。AT&Ts 3B1シリーズUnixシステム用のマニュアルの2つの異なるエディションの比較に基づいています。誰かが親切にこれらのマニュアルの1986年版をスキャンしてオンラインに載せました。これらは、SVR3のオリジナルリリースに対応しています。これecho
は、コマンドがシェルに組み込まれている場合に予期されるUNIX System VユーザーズマニュアルVolume IIの 523ページのリストにはないことがわかります。1987年からSVR3.1マニュアルの私の地元紙コピーでは、echo
されたマニュアルのこのセクションに記載されています。
これはAT&Tが持ち帰ったバークレーのCSRGイノベーションではないと確信しています。4.3BSDは1986年のSVR3と同じ年に登場しましたが、4.3BSDのsh.1マンページを見るとecho
、「特殊コマンド」セクションの組み込みコマンドのリストにないことがわかります。CSRGがこれを行った場合、それを証明するために文書化されたソースが必要になります。
この時点で、echo
SVR3.1よりも前にシェルに組み込まれていたのか、それまでこの事実が文書化されていなかったのか疑問に思うかもしれません。私が利用できる最新のSVR3以前のAT&T Unixソースコードは、PDP-11 System III tarballにあり、そこにはBourneシェルソースコードがあります。echo
にある組み込みコマンドテーブルにはありません/usr/src/cmd/sh/msg.c
。そのファイルのタイムスタンプに基づいて、echo
1980年にはシェルになかったことは確かです。
同じディレクトリには、builtin.c
この質問のポイントを何も含まないというファイルも含まれていますが、この興味深いコメントが見つかります。
/*
builtin commands are those that Bourne did not intend
to be part of his shell.
Redirection of i/o, or rather the lack of it, is still a
problem..
*/
print
ように動作すると言われるksh用の組み込みコマンドがありますecho
。このコマンドは、ISCのAT&T Unix SVR4 2.1 i386などにもあります。print "\012"
エコーと同じ結果が得られます。なぜkshは組み込みでエコーを印刷しないのでしょうか?とにかく本当に面白い。
いくつかのコマンドが組み込まれている3番目の理由があります:外部コマンドの実行が不可能な場合に使用できることです。
システムが非常に壊れて、ls
コマンドが機能しない場合があります。場合によっては、echo *
まだ機能します。
別の(より重要な!)例はkill
次のとおりです。システムが無料のPIDを使い果たすと、実行できません/bin/kill
(PIDが必要だからです:-)が、ビルトインkill
は動作します。
Btw。、which
は外部コマンド(少なくともbashの内部コマンドではない)であるため、内部コマンドをリストすることはできません。例えば:
$ which echo
/bin/echo
$ type -a echo
echo is a shell builtin
echo is /bin/echo
ldconfig
あなたが何をしているのか正確にわからない限り、決して発行しないでください)。また、/ bin、またはさらに悪いことに/ sbinパーティションを吹き飛ばし、まだシェルがロードされている場合はどうなりますか?
ps
コマンドを実行できないため、を使用して手動でPIDを見つける必要があります/proc
。
which
はbashエイリアスであるalias | /usr/bin/which --read-alias ...
ため、外部which
はエイリアスを識別できます(ただし、ビルトインは識別できません)。私はこれを素晴らしいと考えるのか、それとも倒錯するのかを決めることはできません。
Bash Reference Manualによると、それは利便性に関するものです。
シェルは、個別のユーティリティを介して取得することが不可能または不便な機能を実装する組み込みコマンド(組み込み)の小さなセットも提供します。たとえば、cd、break、continue、およびexec)は、シェル自体を直接操作するため、シェルの外部に実装できません。履歴、getopts、kill、またはpwdビルトインなどは、個別のユーティリティで実装できますが、ビルトインコマンドとして使用する方が便利です。すべてのシェル組み込みコマンドについては、以降のセクションで説明します。
高度なbashのスクリプトガイドは、より詳しい説明があります。
「組み込みは、文字通りに内蔵バッシュツールセット内に含まれるコマンドである。これは、パフォーマンス上の理由のいずれかである- 。組み込み関数は、通常、オフフォーク必要とする、より高速な外部コマンドよりも実行する 1 別個のプロセスを-または特定の組み込みは、直接必要があるためシェル内部へのアクセス。」
またecho
、一部のシステムではスタンドアロンユーティリティとして存在することに注意してください。これが私のダーウィンシステム(MacOSX 10.5.8-Leopard)にあるものです
$ uname -a
Darwin host.foo.org 9.8.0 Darwin Kernel Version 9.8.0: Wed Jul 15 16:55:01 PDT 2009; root:xnu-1228.15.4~1/RELEASE_I386 i386
$ bash --version
GNU bash, version 3.2.17(1)-release (i386-apple-darwin9.0)
Copyright (C) 2005 Free Software Foundation, Inc.
$ which echo
/bin/echo
echo
はビルトインとしても利用可能ですが、明らかに私のスクリプトは私のMacでは/ bin / echoを使用し、ほとんどのLinux&FreeBSDシステムではBashビルトインを使用しています。しかし、スクリプトはどこでも正常に機能するため、それは重要ではないようです。
type
。
bhmの答えを補足するために、/bin
誤ってから削除されたとしますPATH
。あなたはそれをecho $PATH
見つけることができるようにしたいでしょう?
echo
現在、ほとんどのシェルには組み込みが含まれていますが、GNU CoreUtilsにはスタンドアロン実装も含まれています。
$ which echo
/bin/echo
$ dpkg -S /bin/echo
coreutils: /bin/echo
GNU Coreutilsがインストールされていないようです(ほとんどのLinuxベースのデスクトップおよびサーバーOSはデフォルトでインストールされていますが、埋め込みLinuxまたは他のUNIXは代わりにシェルユーティリティの代替コレクションを使用する場合があります)。
ところで:あなたが見ればBusyboxの、あなたはそれを参照してくださいよls
、ps
とcat
もそこにコマンドを内蔵している(することができ、少なくともまたは、それが埋め込まシステムのために使われていますし、必要のないすべてが除外することができます)。
/bin/echo
存在しない仮説をサポートしていません。それらは、ビルトインがecho
PATH内のどのプログラムよりも優先されることを示しています。
echo
シェルの組み込みが必要な本当の理由は次のとおりです。
にパスワードがあるとします$PASSWORD
。どのようにファイルに書き込みます./password
か?当然、ほとんどのプログラマーは次のように書きます。
echo "$PASSWORD" >./password
ただし、echo
シェルの組み込みではない場合、パスワードはps
情報を通じてすべてのユーザーに漏洩します。
もちろん、それについて賢くしたい場合はecho
、おそらく他のシェル機能を利用して、なしでパスワードを保存する方法を見つけることができます:
cat >./password <<EOF
${PASSWORD}
EOF
ただし、echo
パスワードをファイルに保存する最も明白な方法も機能するはずなので、組み込みとして持つことは重要なシートベルトです。