终止整个bash脚本而不是子进程

时间:2015-06-28 20:51:30

标签: linux bash signals

我有一个运行多个rsync命令的脚本。当我执行ctrl + c时,只停止运行rsync命令,然后脚本中的下一个命令启动。

如何更改脚本以便ctrl + c将停止整个过程而不只是一个命令?

现在脚本中没有逻辑,只是依次唤醒不同的文件夹。

为了举个例子,我们假设它是

#!/bin/bash
rsync -artv foo/ bar/
rsync -artv another/ folder/

2 个答案:

答案 0 :(得分:1)

最简单的方法是添加:

trap 'exit' INT

在剧本的最开始。

这将在捕获ctrl + c组合时执行exit,并完全停止执行脚本。

答案 1 :(得分:1)

不幸的是,它有点难看。为了确保在按下ctrl-c时bash获得SIGINT,你不能让rsync在前台运行。相反,你需要做类似的事情:

#!/bin/bash

trap 'kill $!; exit 1;' INT
rsync -artv foo/ bar/ &
wait
rsync -artv another/ folder/ &
wait

但这并不完全符合您的要求,因为这会将SIGTERM而不是SIGINT发送到rsync。不幸的是,因为rsync是异步运行的(即在后台运行),所以bash在忽略SIGINT的情况下启动它,所以你不能依赖转发SIGINT。 (很有可能rsync重置其信号处理以接受SIGINT,但通常使用此技术,您应该假设正在运行的作业忽略SIGINT。)

主要问题是如果rsync在前台运行,那么bash不会看到SIGINT,除非您在一个rsync完成之后和下一个rsync开始之前发生它。通过在后台运行作业,bash将看到信号。

请注意,这一点并不健全;这是处理* nix中信号的乐趣之一。