Bash:当有 CTRL-C 时如何中断这个脚本?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2551614/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 21:53:53  来源:igfitidea点击:

Bash: how to interrupt this script when there's a CTRL-C?

bashinterruptcopy-paste

提问by SyntaxT3rr0r

I wrote a tiny Bash script to find all the Mercurial changesets (starting from the tip) that contains the string passed in argument:

我编写了一个很小的 ​​Bash 脚本来查找包含传入参数的字符串的所有 Mercurial 变更集(从提示开始):

#!/bin/bash

CNT=$(hg tip | awk '{ print  }' | head -c 3)
while [ $CNT -gt 0 ]
do
    echo rev $CNT
    hg log -v -r$CNT | grep        
    let CNT=CNT-1
done

If I interrupt it by hitting ctrl-c, more often than not the command currently executed is "hg log" and it's that command that gets interrupted, but then my script continues.

如果我通过按 ctrl-c 来中断它,则当前执行的命令通常是“hg log”并且该命令被中断,但随后我的脚本会继续。

I was then thinking of checking the return status of "hg log", but because I'm piping it into grep I'm not too sure as to how to go about it...

我当时正在考虑检查“hg log”的返回状态,但是因为我正在将它传送到 grep 我不太确定如何去做......

How should I go about exiting this script when it is interrupted? (btw I don't know if that script is good at all for what I want to do but it does the job and anyway I'm interested in the "interrupted" issue)

当脚本被中断时,我应该如何退出这个脚本?(顺便说一句,我不知道该脚本是否适合我想做的事情,但它可以完成工作,无论如何我对“中断”问题很感兴趣)

采纳答案by Dan Story

Rewrite your script like this, using the $PIPESTATUS array to check for a failure:

像这样重写你的脚本,使用 $PIPESTATUS 数组来检查失败:

#!/bin/bash

CNT=$(hg tip | awk '{ print  }' | head -c 3)
while [ $CNT -gt 0 ]
do
    echo rev $CNT
    hg log -v -r$CNT | grep 
    if [ 0 -ne ${PIPESTATUS[0]} ] ; then
            echo hg failed
            exit
    fi     
    let CNT=CNT-1
done

回答by Arkku

Place at the beginning of your script: trap 'echo interrupted; exit' INT

放在脚本的开头: trap 'echo interrupted; exit' INT

Edit:As noted in comments below, probably doesn't work for the OP's program due to the pipe. The $PIPESTATUSsolution works, but it might be simpler to set the script to exit if any program in the pipe exits with an error status: set -e -o pipefail

编辑:正如下面的评论中所指出的,由于管道的原因,可能不适用于 OP 的程序。该$PIPESTATUS解决方案有效,但如果管道中的任何程序退出并显示错误状态,则将脚本设置为退出可能更简单:set -e -o pipefail

回答by Ignacio Vazquez-Abrams

The $PIPESTATUSvariable will allow you to check the results of every member of the pipe.

$PIPESTATUS变量将允许您检查管道的每个成员的结果。