次の行では、「無限」のwhileループを実行していくつかの数字を印刷します。
$ bash -c 'trap stopit SIGINT; run=1; stopit() { run=0; }; while [ $run ]; do for i in {0..4}; do v=$(($i*50)); d=$(for ((k=0;k<=(5+$i);k++)); do echo -n $(($v*(($k+$i)%2))),; done); d=${d%?}; c=$(echo numbers $d); echo $c; sleep 0.1; done; done ; echo Done'
numbers 0,0,0,0,0,0
numbers 50,0,50,0,50,0,50
numbers 0,100,0,100,0,100,0,100
numbers 150,0,150,0,150,0,150,0,150
numbers 0,200,0,200,0,200,0,200,0,200
numbers 0,0,0,0,0,0
numbers 50,0,50,0,50,0,50
numbers 0,100,0,100,0,100,0,100
...
...「拡張」スクリプトは次のとおりです。
trap stopit SIGINT;
run=1;
stopit() {
run=0;
};
while [ $run ]; do
for i in {0..4}; do
v=$(($i*50));
d=$(for ((k=0;k<=(5+$i);k++)); do echo -n $(($v*(($k+$i)%2))),; done);
d=${d%?}; # cut final comma
c=$(echo numbers $d);
echo $c;
sleep 0.1;
done;
done ;
echo Done
while
ループが「永久に」実行され、印刷され(実行中のジョブ)、退屈したらCtrl-Cを押して停止できるというアイデアです。しかし、私が望むのは、メッセージを印刷することです。後ろにCtrl-Cはwhileループを停止します。上記の例では、これはecho Done
コマンドです。
上記の例では、Ctrl-Cを使用して変数をrun
0に設定してループが「完全に」終了するようにし、コマンドを印刷して終了します。残念ながら、Ctrl-Cを押すと何も起こりません。つまり、ループが続き、kill
明示的に実行する必要があります。
上記のスクリプト/行がCtrl-Cのwhileループを終了して最終メッセージを印刷するにはどうすればよいですか?
答え1
わかりました、私の考えでは:
$ bash -c 'trap stopit SIGINT; stopit() { echo Done; exit; }; while [ 1 ]; do for i in {0..4}; do v=$(($i*50)); d=$(for ((k=0;k<=(5+$i);k++)); do echo -n $(($v*(($k+$i)%2))),; done); d=${d%?}; c=$(echo numbers $d); echo $c; sleep 0.1; done; done ;'
numbers 0,0,0,0,0,0
numbers 50,0,50,0,50,0,50
numbers 0,100,0,100,0,100,0,100
numbers 150,0,150,0,150,0,150,0,150
numbers 0,200,0,200,0,200,0,200,0,200
numbers 0,0,0,0,0,0
numbers 50,0,50,0,50,0,50
numbers 0,100,0,100,0,100,0,100
numbers 150,0,150,0,150,0,150,0,150
numbers 0,200,0,200,0,200,0,200,0,200
numbers 0,0,0,0,0,0
Done
デフォルトでは、関数の変数はbash
常にローカルスコープであり、グローバル変数は「隠されている」ので、「グローバル変数をきちんと終了するように変更する」という概念は機能しません。以下を参照してください。
だから読んだら
...最後のコマンド(「echo Done」)をトラップハンドラに移動してから、トラップハンドラで直接実行する方が良いことがわかりましたexit
(「whileループをきちんと終了することを心配しないでください」)。後で印刷するには「問題」