なぜ/ bin / echoがあり、それを使用したいのですか?


52

/bin/echoUbuntu MATE 17.04システムにバイナリ実行可能ファイルがあることに気付きました。

それは奇妙だと思った

$ type echo
echo is a shell builtin

大まかなテストでは/bin/echo、Bashビルトインと同じことを行うことが示唆されていますecho

$ /bin/echo foo
foo
$ /bin/echo $USER
zanna

それでは、なぜechoBashプログラムとは別のバージョンがあるのか、なぜそれをいつ使うのか?



2
@ bodhi.zazenそれは同じではありませんが、この質問の逆を扱っているため、非常に便利です。その質問は、なぜechoシェル組み込みコマンドとして提供されるのかを尋ねるのに対し、これはなぜ外部コマンドとして提供されるのかを尋ねます。
エリアケイガン

3
1つの理由は、誰もがbashを使用するわけではないということです。/ bin / echoはbashよりも前のものであり、開発者は、実行可能ファイルを使用する代わりに、ビルトインとして含めることが有用/効率的であると考えました。
-jamesqf

回答:


87

bashプロンプトを開き、echoコマンドを入力すると、実行ではなくシェル組み込みコマンドが使用され/bin/echoます。/bin/echo存在することが依然として重要である理由は次のとおりです。

  1. 常にシェルを使用しているわけではありません。さまざまな状況下で、シェルを介さずに直接実行可能ファイルを実行します。
  2. 少なくとも理論的には、一部のシェルにはecho組み込み機能がありません。これは実際には必要ありません。

#1の上に展開するには、あなたが名前を始め、すべての通常のファイルを移動したいと仮定abc内のどこsrcにしますdest。それにはいくつかの方法がありますが、そのうちの1つは次のとおりです。

find src -name 'abc*' -type f -exec mv -nv {} dest/ \;

しかし、単にそれを実行するのではなく、最初に実行されるすべてのコマンドを確認したいとします。それでは、echo他のコンテキストと同じように、コマンドの前に追加できます。

find src -name 'abc*' -type f -exec echo mv -nv {} dest/ \;

ただしfind、シェルは使用しません。それは実行され/bin/echoます。

ほかfind-exec-execdir/bin/echo実行ファイル自体がシェルを介してプログラムを実行ではなく、他のプログラムによって呼び出されます。これが起こるxargs(コマンド関連しているfind)、ならびになどの他のコンテキストの数のファイル。もう1つの例は、実行した場合です。これは、動作しているかどうかをテストするのに便利です。Exec=.desktopsudo echosudo

同様に、一部のシェルにはprintf組み込み機能が/usr/bin/printfありますが、存在するものもあります。

意図的に使用する可能性が低い一般的な理由/bin/echoecho、シェルとシェルが提供するコマンドの違いに依存している場合です。man echo文書/bin/echo; help echobash文書bash組み込み。echo同じオペレーティングsystem--上のオペレーティングシステムにまたがるとシェル間の両方-異なる実装ので、非常に移植性がありませんサポート異なるオプション(たとえば、-e)とは、バックスラッシュの処理方法が異なり。もちろん、そのような細部に頼って回避し、使用することをお勧めしますprintfである、代わりにはるかに移植

ではbash、あなたが作ることができるtype組み込みショー/bin/echoにも-と仮定すると/bin、あなたの中にある$PATH、それは常にあるべきな-によってそれを渡す-aフラグ

$ type -a echo
echo is a shell builtin
echo is /bin/echo

21
また、POSIXの仕様では、ある必要があるとされているためです。
グレンジャックマン

4
@glennjackman実際に誰かがそれについての答えを投稿してくれることを望んでいたので、そうすることを決めてほしいです!ただし、Debian、Ubuntu、GNU Coreutils(またはGNUプロジェクト全体)のすべてがPOSIXに準拠しようとしないため、いくつかの微妙な点が関係しています。たとえば、POSIXはcd実行可能ファイルが存在すると主張し実行時にディレクトリを変更して終了し、呼び出し元を以前の場所に残します)、一部のOSには実行可能ファイルがあります。GNU規格で4.1を引用すると役立つかもしれません。
エリアケイガン

@EliahKagan:偶然/ usr / bin / cdには用途があります:/ usr / bin / cd directoryコマンドは、そのディレクトリでそのコマンドを実行します。ディレクトリの変更が失敗すると、コマンドは起動しません。
ジョシュア

4
@Joshuaのより良い使用法cdは、単に特定のディレクトリにアクセスする能力のテストとしてです:/usr/bin/cd some/dir成功した場合、テストした1つのショットで:a)some/dir存在する、b)ディレクトリまたはディレクトリへのリンク、そしてc)そのディレクトリにアクセスするために必要な権限が存在します。すべて自分の状態を変更することなく。
ムル

1
@CarlWitthoft、「printfがechoより優れている理由」を参照してください また/bin/echo\bin\echoWindowsを使用している場合を除き、ではありません。;)
ワイルドカード

31

Eliahはこれに答えてくれましたが、「なぜechoBashプログラムとは別のバージョンがありますか」という部分についてコメントしたいと思います。それは間違った質問です。

正しい質問は、なぜこれが完全に素晴らしい外部コマンドであったかもしれない(そしてそうである)のにそもそも組み込みなのでしょうか?

簡単にするために、ダッシュのビルトイン、わずか38(bashには61があり、比較のためにcompgen -b)の出力を見てください:

.               continue        getopts         readonly        type
:               echo            hash            return          ulimit
[               eval            jobs            set             umask
alias           exec            kill            shift           unalias
bg              exit            local           test            unset
break           export          printf          times           wait
cd              false           pwd             trap
command         fg              read            true

これらのうちいくつが組み込みである必要がありますか?[echofalseprintfpwdtest、とtrueしていない必要があるビルトインする:彼らは唯一の組み込みを行うことができます何もしない(外部コマンドを利用できないシェルの状態に影響を与えたり、入手)。Bash printfは少なくとも組み込みであるという利点を活用printf -v varしますvar。出力を変数に保存します。timebashの特別な機能もあります。キーワードであるため、bashで任意のコマンドリストの時間を計ることができます(dashにはtime同等のものはありません)。pwd組み込みコマンドである必要もありません-外部コマンドは現在の作業ディレクトリを継承します(そして外部コマンドでもあります)。:例外です-NOPが必要:です。残りは、外部コマンドが簡単に実行できるアクションを実行します。

したがって、これらの組み込み関数の5分の1は組み込み関数である必要はありません。どうして?manページには、 *実際にこれらはビルトイン(強調鉱山)である理由を渡しに説明します。dash

ビルトイン
 このセクションでは、組み込みコマンドをリストします。
 個別には実行できない操作を実行する必要がある
 処理する。これらに加えて、いくつかのコマンドがあります。
 効率のために組み込みます(たとえば、printf(1)、echo(1)、test(1)など)。

それだけです。これらのビルトインは、インタラクティブに、スクリプトで頻繁に使用され、シェルがその機能を果たすことができるほど簡単に機能するためです。それが起こるように:。いくつかの(?ほとんどの)シェルはに仕事に**囲碁バックを取ったから2.9 BSD、あなたは見つけることができません組み込みを。shecho

そのため、最小限のシェルでこのようなコマンドを組み込みコマンドとして実装することをスキップできる可能性があります(ただし、現在のシェルはそうではないと思います)。GNU coreutilsプロジェクトは、特定のシェルで実行することを想定していません。POSIXにはこれらのコマンドが必要です。そのため、coreutilsはいずれにしてもこれらを提供し、シェル以外では意味を持たないものはスキップします。


*これは、Almquistシェルの対応するマンページテキストとほぼ同じです。これは、Debian Almquistシェルであるdashのベースとなっているものです。

** zsh極端にこのアイデアを取る:あなたは様々なモジュールをロードすることで取得するコマンド、のようなzmvあなたはシェルの必要性も入ると思わないだろうものです。その時点で、本当の問題は次のとおりです。これらすべてのビルトインを持つzshの代わりにbashを使用する理由は何ですか?


1
:がビルトインである必要はありません。組み込みではないのはばかげている。初期のinit rescue-floppy-diskレベルの問題(この場合、pwdが確実に動作しないという難しい方法を発見した)を扱っていない限り、これをビルトインとして持たないことの唯一のペナルティはひどいパフォーマンスです。
ジョシュア

5
@Joshuaいいえ、:外部は実際にはNOPではないので、PATHあなたが本当に望んでいるのは明示的に何もしない場合でも、ルックアップ、コマンドの実行の試行などがあります。:ビルトインがそれを行うように。
ムル

2
実際には、Bashをpwd組み込み、「論理」パスを表示するデフォルトの動作(pwd -L)で動作するようにする必要があります。 実際に親ディレクトリを表示する動作/bin/pwdのみを実装できpwd -Pcd編集したシンボリックリンクは実装できませんでした。
ピーターコーデス

2
@PeterCordes pwdのステータスはの存在によって少し損なわれてPWDいますが、はい、それは組み込みのステータスを使用して機能を改善するbashのインスタンスでもあります
-muru
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.