Bash 循环 - 在命令中按 Control-C 时如何停止循环?

Ama*_*rus 45 linux unix bash command-line-interface job-control

我正在同步几个目录。我打开了一个 bash 终端,正在执行如下操作:

for DIR in * ; do rsync -a $DIR example.com:somewhere/ ; done
Run Code Online (Sandbox Code Playgroud)

但是,如果我想停止这一切,我按 Control-C。这会停止 rsync,但它会继续进行下一个。在这种情况下,我意识到发生了什么,然后像疯子一样按下 Control-C,直到一切恢复正常。

有什么方法可以“解决”这个问题。我想要它,所以如果我有一个这样的循环,然后按 Control-C,它会将我返回到我的 bash shell。

Ken*_*ter 40

for DIR in * ; do rsync -a $DIR example.com:somewhere/ || break; done
Run Code Online (Sandbox Code Playgroud)

如果单个 rsync 运行由于某种原因失败,这也将退出循环。

  • 附加提示:如果您处于嵌套循环中,并且想要完全终止,请使用 `break 2`(或将“2”替换为要终止的嵌套循环数)。 (6认同)

Ian*_*ung 33

为了扩展丹尼斯的回答,您的代码可能如下所示:

trap "echo Exited!; exit;" SIGINT SIGTERM
Run Code Online (Sandbox Code Playgroud)

有关工作示例(恰好涉及 rsync),请查看http://gist.github.com/279849

  • 我认为最好的答案。捕获“SIGINT”和“SIGTERM”似乎比单独捕获“SIGINT”更一致地杀死无限 while 循环。更新:呃,也许不是。我不知道。我仍然遇到一些需要按 Ctrl + C 两次的情况!我不知道为什么。 (2认同)

Den*_*son 26

您可以为 Control-C 设置陷阱。

trap <command> SIGINT
Run Code Online (Sandbox Code Playgroud)

将在command按下 Control-C 时执行。只需将trap语句放在脚本中您希望它生效的某个位置即可。


Ski*_*rou 9

  1. Ctrl-Z暂停脚本;
  2. kill %%

此答案中的积分,解释和更多详细信息。


amp*_*ine 6

当您将一串命令放在括号内时,该字符串将充当单个进程,并在您点击Ctrl-时接收 SIGINT 并终止C

(for DIR in * ; do rsync -a $DIR example.com:somewhere/ ; done)
Run Code Online (Sandbox Code Playgroud)

但!在rsync命令的情况下,它允许多个来源,所以你写的代码最好写成:

rsync -a * example.com:somewhere/
Run Code Online (Sandbox Code Playgroud)