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