入れ子になったwhileループを終了します。

入れ子になったwhileループを終了します。

基本ループを作成しようとしていますが、親ループを繰り返す間にネストされたループを終了したいと思います。ネストされたループは、親ループが実行されるたびに再起動する必要があります。

#!/bin/bash

loop1=0
i=0

while [[ $loop1 -eq "0" ]]; do

    let "i+=1"
    echo $i "--------------"

    loop2=0
    j=0

    while [[ $loop2 -eq "0" ]]; do

        let "j+=1"
        echo $j $i
        sleep .2    

    done &

    loop2=1
    sleep 2

done

私が望む出力は次のとおりです。

1 --------------
1 1
2 1
3 1
4 1
5 1
6 1
7 1
8 1
9 1
10 1
2 --------------
1 2
2 2
3 2
4 2
5 2
6 2
7 2
8 2
9 2
10 2

対応する出力が得られましたが、元のネストされたループは終了しないため、11 1、12 1、13 1なども得られます。

私はそれが非常に簡単だと確信していますが、それを理解していません。

答え1

この練習の実際の用途は何であるかわかりませんが、バックグラウンドプロセスを終了するにはプロセスIDを保存して$!からkill

背景スクリプト要素は&サブシェル(別のシェルプロセス)で実行されるため、シェル変数への変更はある方向または別の方向には影響しません。 (通常、これは親プロセスに表示されない子プロセスの変更です。通常、子プロセスが完了するのを待つためです。)

これ:

#!/bin/bash

i=0
while true; do   # the loop runs forever, so just use 'true' here
    let "i+=1"
    echo $i "--------------"

    j=0
    while true; do   
        let "j+=1"
        echo $j $i
        sleep .2    
    done &

    pid=$!
    # disown   # remove the comment marker here
    sleep .5   # shorter timeout 
    kill $pid
done

印刷:

1 --------------
1 1
2 1
3 1
2 --------------
1 2
2 2
3 2
loop.sh: line 19:  4113 Terminated              while true; do
    let "j+=1"; echo $j $i; sleep .2;
done
3 --------------
1 3
2 3
...

シェルが子プロセスが終了したことを確認したら、通知を印刷して子プロセスを呼び出してそれらを削除できますdisown(行からコメントを削除)。

答え2

コメントの誰かが "jobs"コマンドとそのコマンドに基づいてプロセスを終了する方法を教えてくれました。これが私がしたことです。最も単純なようです。

i=0
while true; do
    let "i+=1"
    echo $i "--------------"

    j=0
    while true; do
        let "j+=1"
        echo $j $i
        sleep .2    
    done &

    sleep 2

    # jobs
    kill %"$i"
done

関連情報