なぜechoはコマンドに組み込まれたシェルですか?


34
$ which echo
echo: shell built-in command.
$ which ls
/bin/ls
$ which cat
/bin/cat

なぜ、エコーのような独立したユーティリティではありませんlspscatなど?なぜシェル固有なのですか?正当な理由はありますか?


5
これはシェル固有のものであることに注意してください。ZSHはそれを組み込みますが、BASHは組み込みません。
tsvallender

21
@tsv:echo最も確実なの Bash ビルトインです。実際、それはすべての主要な現代のシェルに組み込まれています。
追って通知があるまで一時停止します。

回答:


71

ビルトインには2つのクラスがあります。

  1. 一部のコマンドは、外部の場合は機能できないため、シェルプログラム自体に組み込む必要があります。

    cd外部の場合は、自分のディレクトリしか変更できないため、そのようなものです。シェルの現在の作業ディレクトリには影響しません。(参照:なぜcdプログラムではないのですか?

  2. 他のクラスのコマンドは、純粋に効率化のためにシェルに組み込まれています。

    manページには言及して組み込みコマンドのセクションあり、と、このクラスのコマンドの例としては。dash printfechotest

Unixシステムでは、常に、2番目のクラスのコマンド用に個別の実行可能ファイルが含まれています。これらの個別の実行可能ファイルは、使用する可能性のあるすべてのシェルにも組み込まれていますが、使用したすべてのUnixyシステムで引き続き使用できます。(POSIXでは、実際にこれらの実行可能ファイルが存在する必要があります。)

echoAT&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がこれを行った場合、それを証明するために文書化されたソースが必要になります。

この時点で、echoSVR3.1よりも前にシェルに組み込まれていたのか、それまでこの事実が文書化されていなかったのか疑問に思うかもしれません。私が利用できる最新のSVR3以前のAT&T Unixソースコードは、PDP-11 System III tarballにあり、そこにはBourneシェルソースコードがあります。echoにある組み込みコマンドテーブルにはありません/usr/src/cmd/sh/msg.c。そのファイルのタイムスタンプに基づいて、echo1980年にはシェルになかったことは確かです。


トリビア

同じディレクトリには、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..
*/      

あなたが言及したSysV UM、Vol IIの385ページには、次のprintように動作すると言われるksh用の組み込みコマンドがありますecho。このコマンドは、ISCのAT&T Unix SVR4 2.1 i386などにもあります。print "\012"エコーと同じ結果が得られます。なぜkshは組み込みでエコーを印刷しないのでしょうか?とにかく本当に面白い。

2016年の編集で発掘されるのを待っている数年前の宝石はどれくらいありますか?+1
iruvar

+1。ありがとう。私の(体系的な)読書/学習のために、コマンドをビルトインする目的でソース(参照)を提供してもらえますか?
ティム

体系的に読んだり学習したりするための参考資料、マニュアル、または標準を見つけたいです。bashリファレンスマニュアルとPOSIX仕様で調べてみました。しかし、私はそれを見つけることができません。見逃したかどうかはわかりません。
ティム

@Tim:これと他のここでの答えが説明するように、いくつかのコマンドはシェルに組み込む必要あります。他のすべては純粋にオプションです。それは、基本的に、私のBourneシェルソーススニペットが実際に上記のように言っていることです。そのようなコマンドをシェルに組み込むことはオプションであるため、信頼できる根拠は1人の実装者の意見を与えるだけです。
ウォーレンヤング

19

いくつかのコマンドが組み込まれている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パーティションを吹き飛ばし、まだシェルがロードされている場合はどうなりますか?
ローレンス

PIDを使い果たした場合、どのPIDを削除するかを見つけるのは困難です。psコマンドを実行できないため、を使用して手動でPIDを見つける必要があります/proc
カスペルド

(少なくとも)CentOS whichはbashエイリアスであるalias | /usr/bin/which --read-alias ...ため、外部which エイリアス識別できます(ただし、ビルトイン識別できません)。私はこれを素晴らしいと考えるのか、それとも倒錯するのかを決めることはできません。
-dave_thompson_085

lsコマンドが機能しなくなった時点で、ドライブをboot / masterではなくスレーブとしてマウントし、ファイル構造をそのように修正する必要があると思います。ファイルにエコーする場合を除き、エコーでシステム破損の程度を修正できるかどうかはわかりませんが、修正に長い時間がかかります。システム構造を修正するためのbashスクリプトを作成できることを確認しました。
jonnyjandles

13

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ビルトインを使用しています。しかし、スクリプトはどこでも正常に機能するため、それは重要ではないようです。


3
シェルの組み込みといえば、「which」ではなく「type」を使用する必要があります。
テディ

@Teddyに感謝します。覚えているとき、私はそれを始めました。おかげで人生はずっと良くなりましたtype
ステファンLasiewski


2

echo現在、ほとんどのシェルには組み込みが含まれていますが、GNU CoreUtilsにはスタンドアロン実装も含まれています。

$ which echo
/bin/echo
$ dpkg -S /bin/echo
coreutils: /bin/echo

GNU Coreutilsがインストールされていないようです(ほとんどのLinuxベースのデスクトップおよびサーバーOSはデフォルトでインストールされていますが、埋め込みLinuxまたは他のUNIXは代わりにシェルユーティリティの代替コレクションを使用する場合があります)。

ところで:あなたが見ればBusyboxの、あなたはそれを参照してくださいよlspscatもそこにコマンドを内蔵している(することができ、少なくともまたは、それが埋め込まシステムのために使われていますし、必要のないすべてが除外することができます)。


3
元のポスターのテストは、/bin/echo存在しない仮説をサポートしていません。それらは、ビルトインがechoPATH内のどのプログラムよりも優先されることを示しています。
ウォーレンヤング

1

echoシェルの組み込みが必要な本当の理由は次のとおりです。

にパスワードがあるとします$PASSWORD。どのようにファイルに書き込みます./passwordか?当然、ほとんどのプログラマーは次のように書きます。

echo "$PASSWORD" >./password

ただし、echoシェルの組み込みではない場合、パスワードはps情報を通じてすべてのユーザーに漏洩します。

もちろん、それについて賢くしたい場合はecho、おそらく他のシェル機能を利用して、なしでパスワードを保存する方法を見つけることができます:

cat >./password <<EOF
${PASSWORD}
EOF

ただし、echoパスワードをファイルに保存する最も明白な方法も機能するはずなので、組み込みとして持つことは重要なシートベルトです。


3
有用な副作用ですが、これが理由であるかどうかは非常に疑わしいと思います。
プラグウォッシュ

@DepressedDaniel:何をバックアップしますか?回答をサポートするために使用したリファレンスはどこにありますか?
ジョーカー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.