bash 1行コードでwhileループを中断した後、Ctrl-Cを使用してコマンドを実行しますか?

bash 1行コードでwhileループを中断した後、Ctrl-Cを使用してコマンドを実行しますか?

次の行では、「無限」の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を使用して変数をrun0に設定してループが「完全に」終了するようにし、コマンドを印刷して終了します。残念ながら、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ループをきちんと終了することを心配しないでください」)。後で印刷するには「問題」

おすすめ記事