shループで「do」の後に「;」がないのはなぜですか?

shループで「do」の後に「;」がないのはなぜですか?

1行に書くときにシェルループの後に文字がないのはなぜですか;do

それは私の意味です。複数行にわたって作成すると、forループは次のようになります。

$ for i in $(jot 2)
> do
>     echo $i
> done

一行で:

$ for i in $(jot 2); do echo $i; done

折り畳まれたすべての線が;後ろに表示されます。とは別にこのdo行にが含まれている場合は;エラーです。おそらく私よりはるかにスマートな誰かがこれが正しいことだと思いますが、私はなぜそうなのかわかりません。これは私に一貫性がないようです。

ループにも同じですwhile

$ while something
> do
>     anotherthing
> done
$ while something; do anotherthing; done

答え1

これがコマンドの構文です。バラより複合コマンド

for name [ [in [words …] ] ; ] do commands; done

注意: do commands

ほとんどの人は簡単に読むことができるように、およびをdo別々commandsの行に表示しますが、必須ではありません。次のように書くことができます。

for i in thing
do something
done

私はこの質問が特にシェルに関するものであることを知っており、bashのマニュアルに接続しました。シェルマニュアルにはこのような内容は書かれていませんが、シェルにはこう書かれています。Stephen Byrneが書いた記事バイトマガジンの場合。

スティーブンはこう言いました。

コマンドリスト;改行文字(セミコロン)で区切られた、または終わる1つ以上の単純なコマンドシーケンス。また、次の予約語はするそして完璧通常、改行文字または;...が前に続きます。コマンドのリストは次のとおりです。する処刑される。

答え2

whileこの構文の元の理由が何であるかはわかりませんが、ループが条件付き部分で複数のコマンドを受け入れることができるという事実を考えてみましょう。

while a=$(somecmd);
      [ -n "$a" ];
do
    echo "$a"
done

ここでは、do条件付き部分とループ本文を区別するためにキーワードを使用する必要があります。 and(and)のようなキーワードは、do後にセミコロンや改行文字を必要としませんが、コマンドの直前に現れるという点で、他のキーワードと一貫性があるようです。whileifthendone

他のオプション(ifおよびで一般化while)は少し見苦しく見えます。たとえば、次のように書く必要があります。

if; [ -n "$a" ]; then
    some command here
fi

ループの構文はfor非常に似ています。

答え3

シェル構文はプレフィックスベースです。特別なキーワードで紹介された句があります。特定の用語は組み合わせる必要があります。

ループwhileは1つ以上のテストコマンドで構成されています。

test ; test ; test ; ...

1つ以上の本文コマンドを介して:

body ; body ; body ; ...

何かがシェルにwhileループを開始するように指示する必要があります。この単語の目的は次のとおりですwhile

while test ; test ; test ; ...

ところで状況があいまいになります。テキストを開始するコマンドは何ですか?これを示すための何かがなければならず、それがまさにdoプレフィックスがすることです。

do body ; body ; body ; ...

最後に、最後の本文を見たことを示すものが必要です。特別なキーワードが doneこれを行います。

これらのシェルキーワードは、同じ行にあってもセミコロンで区切る必要はありません。たとえば、複数のネストされたループを閉じるとdone done done ...

... test ; body ... 逆に同じ行にあると、セミコロンがその間に来ます。セミコロンはターミネーターとして理解されます:に属しますtest。したがって、doキーワードの間にキーワードが挿入されると、キーワードはセミコロンとの間になければなりませんbody。セミコロンの反対側にある場合、testコマンド間に配置されず、コマンド構文に誤って含まれます。

シェル構文はもともとStephen Bourneによって設計され、以下からインスピレーションを受けました。アルゴル。 BourneはAlgolが好きで、CをAlgolのように見せるためにシェルソースコードに多くのCマクロを使用しました。あなたはできますUnixバージョン7で1979年のシェルソースコードを参照。マクロは にあり、mac.hどこでも使用されます。たとえば、文は次ifのように表示されます。IFELSEELIFFI

答え4

短い答えは次のとおりです。POSIXシェル構文doとの間のすべての内容はdone一連のステートメントとして扱われ、whileは;シーケンス区切り文字です。

for_clause       : For name                                      do_group
                 | For name                       sequential_sep do_group
                 | For name linebreak in          sequential_sep do_group
                 | For name linebreak in wordlist sequential_sep do_group

do_group         : Do compound_list Done 

sequential_sep   : ';' linebreak
                 | newline_list

また、;標準ではこれを明示的に指定し、必要に応じてsequential_sep後ろに含めますDo

関連情報