printfがyashの組み込みであるかどうかに関するこの質問 から POSIX標準を引用するこの回答 が来ます。
答えは、POSIX検索シーケンスは目的のコマンドの外部実装を見つけることであり、シェルが組み込みとして実装している場合は組み込みを実行することを指摘しています。 (特別な組み込みではない組み込みの場合)
POSIXには、内部実装の実行を許可する前に外部実装が存在するというこの要件があるのはなぜですか?
それは...恣意的であるように思われるので、私は興味があります。
簡単に言うと、実装が標準の外部コマンドをシェルの組み込みとしても使用できるようにする場合でも、ユーザーが見るシェルの動作は変わらないはずです。
私が https://unix.stackexchange.com/a/496291/5132 で示した対比(=一方)の動作間のPD Korn 、MirBSD Korn、およびHeirloom Bourneシェル、(一方で)Z、93 Korn、Bourne Again、およびDebian Almquistシェル、そして(握り手で)渡辺シェルはこれを強調しています。
printf
が組み込まれていないシェルの場合、PATH
から_/usr/bin
_を削除すると、printf
の呼び出しが機能しなくなります。渡部シェルが適合モードで示したPOSIX適合動作は、同じ結果を引き起こします。 printf
が組み込まれているシェルの動作はあたかもであり、外部コマンドを呼び出していました。
一方、_/usr/bin
_がPATH
から削除された場合、すべての非準拠シェルの動作は変更されず、notは、外部コマンドを呼び出しているかのように動作します。
標準があなたに保証しようとしていることは、シェルがあらゆる種類の通常の外部コマンドを組み込むことができる(またはそれらを独自のシェル関数として実装する)ことができ、ビルトインから同じように動作することですPATH
を調整してコマンドが検出されないようにする場合は、外部コマンドを使用します。 PATH
は、呼び出すことができるコマンドを選択および制御するためのツールとして残ります。
( https://unix.stackexchange.com/a/448799/5132 で説明されているように、何年も前に、PATH
の内容を変更することでUnixの個性を選択していました。)
PATH
で見つかるかどうかに関係なく、コマンドを常に機能するにするという意見があるかもしれません実際のところ通常は外部コマンドを組み込みにします。 (それが、私のnoshツールセットが実際にバージョン1.38で組み込みprintenv
コマンドを取得した理由です。これはnotシェルですが。)
しかし、標準では、execvpe()
関数を使用すると、シェルは他のプログラムが同じPATH
で見つけることができない通常の外部コマンドを(見かけ上)魔法のように実行できなくなります。すべてはユーザーの観点から矛盾なく機能し、PATH
はそれがどのように機能するかを制御するためのツールです。
これは非常にばかげているので、シェルがデフォルトモードでシェルを実装していません。
標準の 根拠 とその説明 例 は、これがregularビルトインをパス、およびPATH
内の独自のバイナリをその前に表示することにより、ユーザーがオーバーライドできるようにします(たとえば、/usr/bin/printf
に関連付けられたprintf
組み込みは、/foo/bin/printf
を設定することにより、PATH=/foo/bin:$PATH
外部コマンドによってオーバーライドできます)。
しかし、標準はそれを必要とするようにはなりませんでしたが、何か完全に different (そして役に立たない予期しないものも)。
詳細については、この バグレポート を参照してください。 最終的に受け入れられたテキスト からの引用:
多くの既存の実装は、PATH検索を実行せずに通常の組み込みを実行します。この動作は規範的なテキストと一致せず、スクリプトの作成者が特別に細工されたPATHを介して通常の組み込みユーティリティをオーバーライドすることを許可しません。さらに、根拠は作成者がPATHを変更することで組み込みをオーバーライドできるようにすることです組み込みであると説明していますが、これは規範的なテキストが言うことではありませんです。
FWIW、私も、承認されたテキストから改訂された要件を実装しているシェルはないと思います。