在 bash 单行代码中使用 Ctrl-C 中断 while 循环后运行命令?

在 bash 单行代码中使用 Ctrl-C 中断 while 循环后运行命令?

在下面的一行中,我运行一个“无限”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 循环以之后打印”的事情)

相关内容