26

一般的なコメント:この質問に対する新しい有用な洞察を与える新しい回答には、ボーナスが与えられます。


Bashのリファレンス マニュアルには、Bash が次の for ループ構造をサポートしていると記載されています。

for name [ [in [words ...] ] ; ] do commands; done
for (( expr1 ; expr2 ; expr3 )) ; do commands ; done

驚くべきことに、次の for ループ構造も有効です。

for i in 1 2 3; { echo $i; }
for ((i=1;i<=3;++i)); { echo $i; }

これらの異常な構造はまったく文書化されていません。Bash のマニュアルBash のマンページ、Linux ドキュメンテーション プロジェクトのいずれも、これらの構造について言及していません。

言語の文法を調べると、開閉中かっこ ( { commands; }) を代替として使用することが、for ループと select ステートメントの両方に実装され、 Bash-1.14.7 [1]do commands; doneまでさかのぼる有効な構造であることがわかります。

他の 2 つのループ構造:

until test-commands; do consequent-commands; done
while test-commands; do consequent-commands; done

この代替形式はありません。


多くのシェル言語が関連しているため、これらの構成体もそこで定義され、穏やかに文書化されていることがわかります。KSHマニュアルには次のように記載されています。

do歴史的な理由から、 andの代わりに開きdone括弧と閉じ括弧を使用できます。

for i; { echo $i; } 

一方、ZSHは、他のループ構造に対して同様の代替手段を実装および文書化していますが、制限があります。それは述べています:

、およびコマンドの場合if、どちらの場合も、ループのテスト部分も適切に区切る必要があり ます。whileuntil[[ ... ]](( ... ))


質問:この構造の起源は何ですか? また、これが他のループ構造に伝播されないのはなぜですか?


更新 1:この投稿の下に、非常に有用教育的なコメントがいくつかあり、これは文書化されていない Bourne Shell 機能であり、初期の C-vs-sh 言語の戦いの結果であると思われます。


更新 2:質問をするとき:この言語機能が文書化されていないのはなぜですか? Gnu Bash メーリングリストに投稿したところ、Chet Ramey (現在の GNU bash の主任開発者) から次の回答を受け取りました。

文書化されたことはありません。bash がそれをサポートする理由 (文書化されていません) は、互換性のために実装された文書化されていない Bourne シェル機能だったためです。30 年以上前の当時、それを使用するスクリプトがありました。これらのスクリプトが歴史のごみ箱に入れられることを願っていますが、現在この構造を使用しているスクリプトの数は誰にもわかりません。

文書化しないでおきます。とにかく人々はそれを使うべきではありません。


関連する質問/回答:


脚注: [1]以前のバージョンは見つかりませんでした。これよりも古いバージョンだと思います

4

1 に答える 1