POSIXが特定のシェルビルトインで外部実装を必要とするのはなぜですか?


18

printfがyashの組み込みであるかどうかに関するこの質問から、POSIX標準を引用するこの答えがてきます

答えは、POSIX検索シーケンスは目的のコマンドの外部実装を見つけ、シェルがそれを組み込みとして実装している場合、組み込みを実行することであると指摘しています。(特別なビルトインではないビルトインの場合

POSIXには、内部実装の実行を許可する前に、外部実装が存在するというこの要件があるのはなぜですか?

それは... arbitrary意的だと思うので、私は興味があります。


これは、必要に応じてビルトインを有効/無効にする方法だと思います。
アイザック

2
外部実装を削除してビルトインを無効にしますか?現在、printf使用可能な名前のコマンドはありません。
スタドグ

@studogので、組み込みと同じ名前の空のファイルを作成し、実行ビットをオンにして、PATHのディレクトリに配置します。:P
ワイルドカード

@Wildcard厳密に準拠したシェルは、検索中に名前を確認しPATH、外部スクリプトではなく、組み込みユーティリティを呼び出します。パス内の外部スクリプトを呼び出したい場合はどうしますか?うーん...これは、さまざまな可能性を説明する表を必要とするようです。ここに1つありますが、私には意味がありません。
クサラナンダ

@Kusalananda、あなたの最初の文に関して、それが私のポイントでした。したがって、空のファイルを作成するように言った理由。
ワイルドカード

回答:


15

これは「あたかも」ルールです。

簡単に言えば、実装が標準の外部コマンドをシェル組み込みとしても使用可能にすることを決定した場合、ユーザーが見るシェルの動作は変わらないはずです。

私が/unix//a/496291/5132で示した(一方の)PD Korn、MirBSD Korn、およびHeirloom Bourneシェルの動作の対比。(一方で)Z、93 Korn、Bourne Again、Debian Almquistシェル。そして(握り手で)渡辺貝がこれを強調しています。

printfビルトインとしてないシェルの場合、/usr/binから削除PATHすると、printf動作を停止します。適合モードで渡辺シェルが示すPOSIX適合動作は、同じ結果を引き起こします。printf組み込みのシェルの動作は、外部コマンドを呼び出しているかのようです。

一方、非準拠シェルのすべての動作は、/usr/binから削除された場合は変更され、外部コマンドを呼び出しているかのようには動作しPATHませ

標準が保証しようとしているのは、シェルがあらゆる種類の通常外部コマンドを組み込み(またはそれらを独自のシェル関数として実装)できることであり、組み込みと同じ動作を引き続き行うことができますPATHコマンドが見つからないように調整する場合は、外部コマンドを使用します。 PATH起動できるコマンドを選択および制御するためのツールのままです。

/unix//a/448799/5132で説明されているように、何年も前に人々は、何がオンになっていPATHたかを変更することでUnixの個性を選択しました。)

コマンドを見つけることができるかどうかに関係なく、コマンドを常に機能させることPATH は、実際は、通常は外部コマンドをビルトインするポイントです。(これが、私のnoshツールセットprintenvがバージョン1.38で組み込みコマンドを取得した理由です。実際、これはシェルではありませんが。)

ただし、標準では、関数を呼び出す他の非シェルプログラムから見られるように、シェルから起動していない通常の外部コマンドに対して同じ動作が見られるという保証が与えられており、シェルは魔法のようにはできません他のプログラムが同じで見つけることができない通常の外部コマンドを(明らかに)実行します。すべてはユーザーの観点から一貫して機能し、その動作を制御するためのツールです。PATHexecvpe()PATHPATH

参考文献


13

それは非常に馬鹿げているので、デフォルトモードでそれを実装しているシェルはありません。

標準の理論的根拠とそのは、これがパスに関連付けられた通常のビルトインを持っている失敗した試みであり、ユーザーが自分のバイナリをその前に表示することでそれをオーバーライドできることを示唆しているPATH(例えばprintf、に関連付けられたビルトイン)を設定/usr/bin/printfすることにより、/foo/bin/printf外部コマンドによってオーバーライドできますPATH=/foo/bin:$PATH

しかし、標準はそれを要求することにはなりませんでしたが、完全に異なるものを必要としました(また、役に立たず、予期していませんでした)。

詳細については、このバグレポートをご覧ください。最終的に受け入れられたテキストからの引用:

多くの既存の実装は、PATH検索を実行せずに通常の組み込みを実行します。この動作は規範的なテキストと一致せず、スクリプト作成者が特別に細工されたPATHを介して通常の組み込みユーティリティをオーバーライドすることはできません。さらに、その根拠は、作成者が PATHを変更することでビルトインをオーバーライドできるようにすることであると説明していますが、これは規範的なテキストには書かれていません

FWIW、受け入れられたテキストから改訂された要件を実装するシェルも存在しないと思います。


article.gmane.org/gmane.comp.standards.posix.austin.general/…の議論も参照してください(他にもいくつかあります)。
ステファンシャゼル


いいえ、(たとえば、/ usr / bin / printfに関連付けられているprintfビルトインは、PATH = / foo / bin:$ PATHを設定することにより、/ foo / bin / printf外部コマンドによってオーバーライドできます)。、それは間違っています。/ both / any of /usr/bin/printfまたは/foo/bin/printfPATHに存在すると、組み込みの printf がアクティブになります。不足している(PATH内の)外部printfが行うことは、組み込みを無効にすることだけです。(仕様による)。
アイザック
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.